FreeCalypso > hg > fc-magnetite
view src/cs/layer1/audio_cfile/l1audio_sync.c @ 639:026c98f757a6
tpudrv12.h & targets/gtm900.h: our current support is for MGC2GSMT version only
As it turns out, there exist two different Huawei-made hw platforms both
bearing the marketing name GTM900-B: one is MG01GSMT, the other is MGC2GSMT.
The two are NOT fw-compatible: aside from flash chip differences which
should be handled by autodetection, the two hw platforms are already known
to have different RFFEs with different control signals, and there may be
other differences not yet known. Our current gtm900 build target is for
MGC2GSMT only; we do not yet have a specimen of MG01GSMT on hand, hence
no support for that version will be possible until and unless someone
provides one.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 30 Jan 2020 18:19:01 +0000 |
parents | 11e279107681 |
children |
line wrap: on
line source
/************* Revision Controle System Header ************* * GSM Layer 1 software * L1AUDIO_SYNC.C * * Filename l1audio_sync.c * Copyright 2003 (C) Texas Instruments * ************* Revision Controle System Header *************/ /************************************/ /* Include files... */ /************************************/ #include "l1_macro.h" #include "l1_confg.h" #if (AUDIO_TASK == 1) #include "l1_types.h" #include "sys_types.h" #if (CODE_VERSION == SIMULATION) && (AUDIO_SIMULATION) #include <stdlib.h> #include <string.h> #include "iq.h" // Debug / Init hardware ("eva3.lib") #include "l1_ver.h" #include "l1_const.h" #include "l1_signa.h" #if TESTMODE #include "l1tm_defty.h" #endif #include "l1audio_const.h" #include "l1audio_cust.h" #include "l1audio_signa.h" #include "l1audio_defty.h" #include "l1audio_msgty.h" #if (L1_GTT == 1) #include "l1gtt_const.h" #include "l1gtt_defty.h" #endif #if (L1_MP3 == 1) #include "l1mp3_const.h" #include "l1mp3_defty.h" #endif #if (L1_MIDI == 1) #include "l1midi_const.h" #include "l1midi_defty.h" #endif #if (L1_AAC == 1) #include "l1aac_const.h" #include "l1aac_defty.h" #endif #include "l1_defty.h" #include "cust_os.h" #include "l1_msgty.h" #include "l1_varex.h" #include "l1_mftab.h" #include "l1_tabs.h" #include "l1_ctl.h" #include "l1_time.h" #include "l1_scen.h" #if (L1_STEREOPATH == 1) #include "sys_dma.h" #include "abb.h" #if TESTMODE #include "l1tm_msgty.h" #endif #include "l1audio_stereo.h" #endif #include "mem.h" #else // Layer1 and debug include files. #include <ctype.h> #include <math.h> #include "l1_ver.h" #include "l1_const.h" #include "l1_signa.h" #if TESTMODE #include "l1tm_defty.h" #endif #include "l1audio_const.h" #include "l1audio_cust.h" #include "l1audio_signa.h" #include "l1audio_defty.h" #include "l1audio_msgty.h" #if (L1_GTT == 1) #include "l1gtt_const.h" #include "l1gtt_defty.h" #endif #if (L1_MP3 == 1) #include "l1mp3_const.h" #include "l1mp3_defty.h" #endif #if (L1_MIDI == 1) #include "l1midi_const.h" #include "l1midi_defty.h" #endif #if (L1_AAC == 1) #include "l1aac_const.h" #include "l1aac_defty.h" #endif #include "l1_defty.h" #include "cust_os.h" #include "l1_msgty.h" #include "tpudrv.h" // TPU drivers. ("eva3.lib") #include "l1_varex.h" #include "l1_proto.h" #include "l1_mftab.h" #include "l1_tabs.h" #include "mem.h" #include "armio.h" #include "timer.h" #include "timer1.h" #include "dma.h" #include "inth.h" #include "ulpd.h" #include "rhea_arm.h" #include "clkm.h" // Clockm ("eva3.lib") #include "l1_ctl.h" #include "l1_time.h" #if L2_L3_SIMUL #include "l1_scen.h" #endif #if (L1_STEREOPATH == 1) #include "sys_dma.h" #include "abb.h" #if TESTMODE #include "l1tm_msgty.h" #endif #include "l1audio_stereo.h" #endif #include "mem.h" #endif #include "l1audio_macro.h" #include "l1_trace.h" #if (CHIPSET == 15) && (CODE_VERSION != SIMULATION) #include "bspTwl3029.h" #include "bspTwl3029_I2c.h" #include "bspTwl3029_Aud_Map.h" #include "bspTwl3029_Int_Map.h" #endif /**************************************/ /* Prototypes for L1 SYNCH manager */ /**************************************/ void l1s_audio_manager(void); #if (KEYBEEP) void l1s_keybeep_manager(void); #endif #if (TONE) void l1s_tone_manager(void); #endif #if (L1_CPORT == 1) void l1s_cport_manager(void); #endif #if (MELODY_E1) void l1s_melody0_manager(void); void l1s_melody1_manager(void); #endif #if (VOICE_MEMO) void l1s_vm_play_manager (void); void l1s_vm_record_manager(void); void l1s_tone_ul_manager (void); #endif #if (L1_PCM_EXTRACTION) void l1s_pcm_download_manager (void); void l1s_pcm_upload_manager (void); #endif #if (L1_VOICE_MEMO_AMR) void l1s_vm_amr_play_manager (void); void l1s_vm_amr_record_manager(void); #endif #if (SPEECH_RECO) void l1s_sr_enroll_manager (void); void l1s_sr_update_manager (void); void l1s_sr_reco_manager (void); void l1s_sr_processing_manager(void); void l1s_sr_speech_manager (void); #endif #if (AEC == 1) void l1s_aec_manager (void); #endif #if (AEC == 2) void l1s_aec_manager (void); #endif #if (FIR) void l1s_fir_manager (void); void l1s_fir_set_params (void); #endif #if (AUDIO_MODE) void l1s_audio_mode_manager (void); #endif #if (MELODY_E2) void l1s_melody0_e2_manager(void); void l1s_melody1_e2_manager(void); #endif #if (L1_MP3 == 1) void l1s_mp3_manager(void); #endif #if (L1_MIDI == 1) void l1s_midi_manager(void); #endif #if (L1_AAC == 1) void l1s_aac_manager(void); #endif #if (L1_EXTERNAL_AUDIO_VOICE_ONOFF == 1) void l1s_audio_onoff_manager(void); #endif #if (L1_EXT_MCU_AUDIO_VOICE_ONOFF == 1) void l1s_audio_voice_onoff_manager(void); #endif #if (L1_STEREOPATH == 1) void l1s_stereopath_drv_manager(void); #endif #if (L1_ANR == 1 || L1_ANR == 2) void l1s_anr_manager(void); #endif #if (L1_IIR == 1 || L1_IIR == 2) void l1s_iir_manager(void); #endif #if (L1_WCM == 1) void l1s_wcm_manager(void); #endif #if (L1_AGC_UL == 1) void l1s_agc_ul_manager(void); #endif #if (L1_AGC_DL == 1) void l1s_agc_dl_manager(void); #endif #if (L1_DRC == 1) void l1s_drc_manager(void); #endif #if (L1_LIMITER == 1) void l1s_limiter_manager(void); #endif #if (L1_ES == 1) void l1s_es_manager(void); #endif void l1s_audio_it_manager(void); /**************************************/ /* External prototypes */ /**************************************/ extern UWORD8 copy_data_from_buffer (UWORD8 session_id, UWORD16 *buffer_size, UWORD16 **ptr_buf, UWORD16 data_size, API *ptr_dst); extern UWORD8 copy_data_to_buffer (UWORD8 session_id, UWORD16 *buffer_size, UWORD16 **ptr_buf, UWORD16 data_size, API *ptr_src); extern UWORD8 Cust_get_pointer (UWORD16 **ptr, UWORD16 *buffer_size, UWORD8 session_id); #if (MELODY_E2) extern UWORD16 audio_twentyms_to_TDMA_convertion (UWORD16 twentyms_value); #endif #if (MELODY_E2) || (L1_VOICE_MEMO_AMR) extern UWORD8 copy_byte_data_from_buffer (UWORD8 session_id, UWORD16 *buffer_size, UWORD8 **ptr_buf, UWORD16 data_size, UWORD8 *ptr_dst); extern UWORD8 copy_byte_data_to_buffer (UWORD8 session_id, UWORD16 *buffer_size, UWORD8 **ptr_buf, UWORD16 data_size, UWORD8 *ptr_src); #endif #if (L1_VOICE_MEMO_AMR) extern UWORD8 copy_byte_data_le_from_buffer (UWORD8 session_id, UWORD16 *buffer_size, UWORD8 **ptr_buf, UWORD16 data_size, API *ptr_dst); extern UWORD8 copy_byte_data_le_to_buffer (UWORD8 session_id, UWORD16 *buffer_size, UWORD8 **ptr_buf, UWORD16 data_size, API *ptr_src); #endif #if (L1_LIMITER == 1) void l1_audio_lim_update_mul_low_high (); #endif #if (L1_AGC_UL == 1) extern void l1_audio_agc_ul_copy_params(); #endif #if (L1_AGC_DL == 1) extern void l1_audio_agc_dl_copy_params(); #endif #if (L1_IIR == 2) extern void l1_audio_iir4x_copy_params(); #endif #if (L1_DRC == 1) extern void l1_audio_drc1x_copy_params(); #endif // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) static void l1s_audio_ul_onoff_manager(); static void l1s_audio_dl_onoff_manager(); void l1_audio_abb_ul_on_callback(void); void l1_audio_abb_ul_off_callback(void); void l1_audio_abb_dl_on_callback(void); void l1_audio_abb_dl_off_callback(void); void l1_audio_abb_ul_off_dl_off_callback(void); void l1_audio_abb_ul_off_dl_on_callback(void); void l1_audio_abb_ul_on_dl_off_callback(void); void l1_audio_abb_ul_on_dl_on_callback(void); void l1_audio_ul_onoff_trace(); void l1_audio_dl_onoff_trace(); #if (CODE_VERSION != SIMULATION) BspTwl3029_ReturnCode l1_outen_update(void); #endif #if (CODE_VERSION == SIMULATION) signed char l1_outen_update(void); #endif #endif // L1_AUDIO_MCU_ONOFF #if (CODE_VERSION == SIMULATION)&&(L1_AUDIO_MCU_ONOFF == 1) // Triton Audio ON/OFF Changes void l1_audio_abb_ul_on_req ( void(*callback_fn)(void) ); void l1_audio_abb_dl_on_req ( void(*callback_fn)(void) ); void l1_audio_abb_ul_off_req ( void(*callback_fn)(void) ); void l1_audio_abb_dl_off_req ( void(*callback_fn)(void) ); void l1_audio_abb_ul_off_dl_off_req ( void(*callback_fn)(void) ); void l1_audio_abb_ul_off_dl_on_req ( void(*callback_fn)(void) ); void l1_audio_abb_ul_on_dl_off_req ( void(*callback_fn)(void) ); void l1_audio_abb_ul_on_dl_on_req ( void(*callback_fn)(void) ); #endif #if (ANLG_FAM == 11) //sundi: add the abb_write_done variable for I2C write acknowledgement //UWORD8 abb_write_done = 0; #endif /*-------------------------------------------------------*/ /* l1s_audio_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Global manager of the L1S audio task. */ /* */ /*-------------------------------------------------------*/ void l1s_audio_manager(void) { BOOL l1_audio_it_com = FALSE; // Initialize the ITCOM for audio task l1s.l1_audio_it_com = FALSE; #if (KEYBEEP) // the keybeep task is activated? if ((l1a_l1s_com.keybeep_task.command.start) || (l1s.audio_state[L1S_KEYBEEP_STATE] != 0)) { l1s_keybeep_manager(); l1_audio_it_com = TRUE; } #endif #if (TONE) // the tone task is activated? if ((l1a_l1s_com.tone_task.command.start) || (l1s.audio_state[L1S_TONE_STATE] != 0)) { l1s_tone_manager(); l1_audio_it_com = TRUE; } #endif #if (MELODY_E1) /* FreeCalypso: reconstructed from TCS211 object */ #if (MELODY_E2) if (l1s.melody_e2.dsp_task == FALSE) { #endif // the melody0 task is activated? if ((l1a_l1s_com.melody0_task.command.start) || (l1s.audio_state[L1S_MELODY0_STATE] != 0)) { l1s_melody0_manager(); l1_audio_it_com = TRUE; } // the melody1 task is activated? if ((l1a_l1s_com.melody1_task.command.start) || (l1s.audio_state[L1S_MELODY1_STATE] != 0)) { l1s_melody1_manager(); l1_audio_it_com = TRUE; } #if (MELODY_E2) } #endif #endif #if (VOICE_MEMO) // the voicememo playing task is activated? if ((l1a_l1s_com.voicememo_task.play.command.start) || (l1s.audio_state[L1S_VM_PLAY_STATE] != 0)) { l1s_vm_play_manager(); l1_audio_it_com = TRUE; } else // voicememo playing task and voice memo recoding task isn't compatible { // the voicememo recording task is activated? if ((l1a_l1s_com.voicememo_task.record.command.start) || (l1s.audio_state[L1S_VM_RECORD_STATE] != 0)) { l1s_vm_record_manager(); l1_audio_it_com = TRUE; } // the voicememo tone uplink task is activated? if ((l1a_l1s_com.voicememo_task.record.tone_ul.start) || (l1s.audio_state[L1S_TONE_UL_STATE] != 0)) { l1s_tone_ul_manager(); l1_audio_it_com = TRUE; } } #endif #if (L1_PCM_EXTRACTION) // the PCM download task is activated? if ((l1a_l1s_com.pcm_task.download.command.start) || (l1s.audio_state[L1S_PCM_DOWNLOAD_STATE] != 0)) { l1s_pcm_download_manager(); l1_audio_it_com = TRUE; } // the PCM upload task is activated? if ((l1a_l1s_com.pcm_task.upload.command.start) || (l1s.audio_state[L1S_PCM_UPLOAD_STATE] != 0)) { l1s_pcm_upload_manager(); l1_audio_it_com = TRUE; } #endif /* L1_PCM_EXTRACTION */ #if (L1_VOICE_MEMO_AMR) // the voicememo playing task is activated? if ((l1a_l1s_com.voicememo_amr_task.play.command.start) || (l1s.audio_state[L1S_VM_AMR_PLAY_STATE] != 0)) { l1s_vm_amr_play_manager(); l1_audio_it_com = TRUE; } else // voicememo playing task and voice memo recoding task isn't compatible { // the voicememo recording task is activated? if ((l1a_l1s_com.voicememo_amr_task.record.command.start) || (l1s.audio_state[L1S_VM_AMR_RECORD_STATE] != 0)) { l1s_vm_amr_record_manager(); l1_audio_it_com = TRUE; } } #endif #if (SPEECH_RECO) // the speech recognition enroll task is activated? if ((l1a_l1s_com.speechreco_task.command.enroll_start) || (l1s.audio_state[L1S_SR_ENROLL_STATE] != 0)) { l1s_sr_enroll_manager(); l1_audio_it_com = TRUE; } else // the speech recognition update task is activated? if ((l1a_l1s_com.speechreco_task.command.update_start) || (l1s.audio_state[L1S_SR_UPDATE_STATE] != 0)) { l1s_sr_update_manager(); l1_audio_it_com = TRUE; } else // the speech recognition reco task is activated? if ((l1a_l1s_com.speechreco_task.command.reco_start) || (l1s.audio_state[L1S_SR_RECO_STATE] != 0)) { l1s_sr_reco_manager(); l1_audio_it_com = TRUE; } else // the speech recognition processing task is activated? if ((l1a_l1s_com.speechreco_task.command.processing_start) || (l1s.audio_state[L1S_SR_PROCESSING_STATE] != 0)) { l1s_sr_processing_manager(); l1_audio_it_com = TRUE; } // the speech recognition speech recording task is activated? if ((l1a_l1s_com.speechreco_task.command.speech_start) || (l1s.audio_state[L1S_SR_SPEECH_STATE] != 0)) { l1s_sr_speech_manager(); l1_audio_it_com = TRUE; } #endif #if (AEC == 1) // the AEC is activated? if ((l1a_l1s_com.aec_task.command.start) || (l1s.audio_state[L1S_AEC_STATE] != 0)) { l1s_aec_manager(); // It's not necessary to enable the IT DSP because the // AEC works with the dedicated speech therefor an IT DSP is // already requested by the modem } #endif #if (AEC == 2) // the AEC is activated? if ((l1a_l1s_com.aec_task.command.start) || (l1s.audio_state[L1S_AEC_STATE] != 0)) { l1s_aec_manager(); l1_audio_it_com = TRUE; } #endif #if (FIR) // the FIR is activated? if (l1a_l1s_com.fir_task.command.start) { l1s_fir_manager(); l1_audio_it_com = TRUE; } #endif #if (AUDIO_MODE) // the AUDIO MODE is activated? if (l1a_l1s_com.audio_mode_task.command.start) { l1s_audio_mode_manager(); l1_audio_it_com = TRUE; } #endif #if (MELODY_E2) // Handling counters if (l1s.melody_e2.dsp_task == TRUE) { l1s.melody_e2.timebase++; l1s.melody_e2.timebase_mod_60ms++; if (l1s.melody_e2.timebase_mod_60ms == 13) l1s.melody_e2.timebase_mod_60ms = 0; } else { l1s.melody_e2.timebase = 0; l1s.melody_e2.timebase_mod_60ms = 0; } // Update the oscillator active fields with DSP active oscillators l1s.melody_e2.global_osc_active = l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_osc_active; l1s.melody_e2.global_osc_to_start = 0; // oscillator active fields can't be updated until dsp has acknowledged new notes if (l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_semaphore == 0) { l1s.melody0_e2.oscillator_active &= l1s.melody_e2.global_osc_active; l1s.melody1_e2.oscillator_active &= l1s.melody_e2.global_osc_active; } // Both states machines are inactive => Start or Stop DSP module if ( (l1s.audio_state[L1S_MELODY0_E2_STATE] == 0) && (l1s.audio_state[L1S_MELODY1_E2_STATE] == 0) ) { // Start command + DSP module not running => Start DSP module if( ((l1a_l1s_com.melody0_e2_task.command.start) || (l1a_l1s_com.melody1_e2_task.command.start)) && (l1s.melody_e2.dsp_task == FALSE) ) { // Set the bit TONE to do the init only at the first start // of the first melody (in case of 2 melodies) // Select the melody E2 instead of E1 or tones l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = MELODY_E2_SELECTED; l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (B_MELO | B_TONE); l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_deltatime = 0; // set delta_time as non valid l1s.melody0_e2.delta_time = 0xFFFF; l1s.melody1_e2.delta_time = 0xFFFF; // Set the flag to confirm that the DSP melody E2 task is started l1s.melody_e2.dsp_task = TRUE; } // No command, DSP module running => Stop DSP module else if (l1s.melody_e2.dsp_task) { // The 2 melodies are stopped therefore the DSP must be // stopped so the bit B_MELO must be reset. /* FreeCalypso TCS211 reconstruction from disassembly */ if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & (B_MELO | B_TONE)) { if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & (B_MELO|B_TONE))) { l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = MELODY_E2_SELECTED; l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (B_MELO | B_TONE); } l1_audio_it_com = TRUE; } else { l1s.melody_e2.dsp_task = FALSE; } /* end of reconstructed section */ } } // the melody0 task is activated? if ( (l1a_l1s_com.melody0_e2_task.command.start) || (l1s.audio_state[L1S_MELODY0_E2_STATE] != 0) ) { l1s_melody0_e2_manager(); l1_audio_it_com = TRUE; } // the melody0 task is activated? if ( (l1a_l1s_com.melody1_e2_task.command.start) || (l1s.audio_state[L1S_MELODY1_E2_STATE] != 0) ) { l1s_melody1_e2_manager(); l1_audio_it_com = TRUE; } // We updated some oscillators so we must set the semaphore if (l1s.melody_e2.global_osc_to_start != 0x0000) { // Set the melody E2 semaphore l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_semaphore = 0x0001; // Update delta_time by min_delta_time(melo0, melo1) l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_deltatime = l1s.melody0_e2.delta_time; if (l1s.melody1_e2.delta_time < l1s.melody0_e2.delta_time) l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_deltatime = l1s.melody1_e2.delta_time; l1s.melody0_e2.delta_time = 0xFFFF; l1s.melody1_e2.delta_time = 0xFFFF; } #endif #if (L1_MP3 == 1) if ((l1a_l1s_com.mp3_task.command.start) || (l1s.audio_state[L1S_MP3_STATE] != 0)) { l1s_mp3_manager(); l1_audio_it_com=TRUE; } #endif // L1_MP3 #if (L1_AAC == 1) if ((l1a_l1s_com.aac_task.command.start) || (l1s.audio_state[L1S_AAC_STATE] != 0)) { l1s_aac_manager(); l1_audio_it_com=TRUE; } #endif // L1_AAC #if (L1_CPORT == 1) // the Cport task is activated? if ((l1a_l1s_com.cport_task.command.start) || (l1s.audio_state[L1S_CPORT_STATE] != 0)) { l1s_cport_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_EXTERNAL_AUDIO_VOICE_ONOFF == 1) // the audio on off task is activated? if (l1a_l1s_com.audio_onoff_task.command.start || (l1s.audio_state[L1S_AUDIO_ONOFF_STATE] != 0)) { l1s_audio_onoff_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_EXT_MCU_AUDIO_VOICE_ONOFF == 1) // the audio on off task is activated? if (l1a_l1s_com.audio_onoff_task.command.start || (l1s.audio_state[L1S_AUDIO_ONOFF_STATE] != 0)) { l1s_audio_voice_onoff_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_STEREOPATH == 1) // the Stereopath task is activated? if ((l1a_l1s_com.stereopath_drv_task.command.start) || (l1s.audio_state[L1S_STEREOPATH_DRV_STATE] != 0)) { l1s_stereopath_drv_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_ANR == 1 || L1_ANR == 2) // the ANR task is activated? if (l1a_l1s_com.anr_task.command.update || (l1s.audio_state[L1S_ANR_STATE] != 0)) { l1s_anr_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_IIR == 1 || L1_IIR == 2) // the IIR task is activated? if (l1a_l1s_com.iir_task.command.update || (l1s.audio_state[L1S_IIR_STATE] != 0)) { l1s_iir_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_WCM == 1) // the WCM task is activated? if (l1a_l1s_com.wcm_task.command.update || (l1s.audio_state[L1S_WCM_STATE] != 0)) { l1s_wcm_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_DRC == 1) // the DRC task is activated? if (l1a_l1s_com.drc_task.command.update || (l1s.audio_state[L1S_DRC_STATE] != 0)) { l1s_drc_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_AGC_UL == 1) // the AGC UL task is activated? if (l1a_l1s_com.agc_ul_task.command.update || (l1s.audio_state[L1S_AGC_UL_STATE] != 0)) { l1s_agc_ul_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_AGC_DL == 1) // the AGC DL task is activated? if (l1a_l1s_com.agc_dl_task.command.update || (l1s.audio_state[L1S_AGC_DL_STATE] != 0)) { l1s_agc_dl_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_LIMITER == 1) // the LIMITER task is activated? if (l1a_l1s_com.limiter_task.command.update || l1a_l1s_com.limiter_task.command.partial_update || (l1s.audio_state[L1S_LIMITER_STATE] != 0)) { l1s_limiter_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_ES == 1) // the echo suppressor task is activated? if (l1a_l1s_com.es_task.command.update || (l1s.audio_state[L1S_ES_STATE] != 0)) { l1s_es_manager(); l1_audio_it_com = TRUE; } #endif #if 0 /* FreeCalypso: LoCosto-ism not present in TCS211 */ // the audio It task is activated? if (l1a_l1s_com.audioIt_task.command.start) { l1s_audio_it_manager(); l1_audio_it_com = TRUE; } #endif #if (L1_MIDI == 1) if ((l1a_l1s_com.midi_task.command.start) || (l1s.audio_state[L1S_MIDI_STATE] != 0)) { l1s_midi_manager(); l1_audio_it_com=TRUE; } #endif // L1_MIDI #if 0 /* FreeCalypso: LoCosto-ism not present in TCS211 */ // The audio IT shall be foprwarded to the DSP in case the L1S is forcing the audio if (l1a_l1s_com.audio_forced_by_l1s == TRUE) l1_audio_it_com = TRUE; #endif l1s.l1_audio_it_com = l1_audio_it_com; } #if (L1_AUDIO_MCU_ONOFF == 1) void l1s_audio_onoff_manager(void) { T_L1S_AUDIO_ONOFF_MANAGER *onoff_ctl = &(l1s.audio_on_off_ctl); //l1_audio_onoff_entry_sim_log(); #if (AUDIO_DEBUG == 1) trace_info.audio_debug_var.ul_state = l1s.audio_state[L1S_AUDIO_UL_ONOFF_STATE]; trace_info.audio_debug_var.dl_state = l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE]; trace_info.audio_debug_var.ul_onoff_counter = onoff_ctl->l1_audio_switch_on_ul_request; trace_info.audio_debug_var.dl_onoff_counter = onoff_ctl->l1_audio_switch_on_dl_request; #endif l1s_audio_ul_onoff_manager(); l1s_audio_dl_onoff_manager(); // Call the driver depending on the actions switch(onoff_ctl->l1_audio_ul_action) { case L1_AUDIO_NO_ACTION: { switch(onoff_ctl->l1_audio_dl_action) { case L1_AUDIO_NO_ACTION: { // UL No Action and DL No Action Do nothing } break; case L1_AUDIO_TURN_ON: { // UL No Action and DL Turn on l1_audio_abb_dl_on_req(l1_audio_abb_dl_on_callback); } break; case L1_AUDIO_TURN_OFF: { // UL No Action and DL Turn off l1_audio_abb_dl_off_req(l1_audio_abb_dl_off_callback); } break; default: { // Invalid Action send error trace here } break; } // end switch(l1_audio_dl_action) } break; case L1_AUDIO_TURN_ON: { switch(onoff_ctl->l1_audio_dl_action) { case L1_AUDIO_NO_ACTION: { // UL Action ON and DL No Action l1_audio_abb_ul_on_req(l1_audio_abb_ul_on_callback); } break; case L1_AUDIO_TURN_ON: { // UL Action ON and DL Action ON l1_audio_abb_ul_on_dl_on_req(l1_audio_abb_ul_on_dl_on_callback); } break; case L1_AUDIO_TURN_OFF: { // UL Action ON and DL Action OFF l1_audio_abb_ul_on_dl_off_req(l1_audio_abb_ul_on_dl_off_callback); } break; default: { // Invalid Action Send error trace here } break; } // end switch(l1_audio_dl_action) } break; case L1_AUDIO_TURN_OFF: { switch(onoff_ctl->l1_audio_dl_action) { case L1_AUDIO_NO_ACTION: { // UL Action OFF DL No Action l1_audio_abb_ul_off_req(l1_audio_abb_ul_off_callback); } break; case L1_AUDIO_TURN_ON: { // UL Action OFF DL Action ON l1_audio_abb_ul_off_dl_on_req(l1_audio_abb_ul_off_dl_on_callback); } break; case L1_AUDIO_TURN_OFF: { // UL Action OFF DL Action OFF l1_audio_abb_ul_off_dl_off_req(l1_audio_abb_ul_off_dl_off_callback); } break; default: { } break; } // end switch(l1_audio_dl_action) } break; default: { // Invalid Action send error trace here } break; } // end switch(l1_audio_ul_action) } // end l1s_audio_triton_onoff_manager() static void l1s_audio_ul_onoff_manager() { T_L1S_AUDIO_ONOFF_MANAGER *onoff_ctl = &(l1s.audio_on_off_ctl); UWORD8 *state = &l1s.audio_state[L1S_AUDIO_UL_ONOFF_STATE]; onoff_ctl->l1_audio_ul_action = L1_AUDIO_NO_ACTION; if(onoff_ctl->l1_audio_switch_on_ul_request >= 1) { // At least one module requires UL audio path to be on switch(*state) { case L1_AUDIO_UL_OFF: { // UL audio path is OFF and needs to be started onoff_ctl->l1_audio_ul_on2off_hold_time = L1_AUDIO_ON2OFF_UL_HOLD_TIME; onoff_ctl->l1_audio_ul_action = L1_AUDIO_TURN_ON; *state = L1_AUDIO_UL_SWITCHON_STARTED; onoff_ctl->l1_audio_ul_switched_on = FALSE; onoff_ctl->l1_audio_ul_switched_off = TRUE; } break; case L1_AUDIO_UL_SWITCHON_STARTED: { // UL audio path in the process of turning on // Check if it is turned on, if so change state to UL on if(onoff_ctl->l1_audio_ul_switched_on == TRUE) { onoff_ctl->l1_audio_ul_switched_off = FALSE; *state = L1_AUDIO_UL_ON; } #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_UL_ON: { // UL audio path is on and some module wants it to be so // Do nothing essentially except initialize the hold time onoff_ctl->l1_audio_ul_on2off_hold_time = L1_AUDIO_ON2OFF_UL_HOLD_TIME; #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_UL_SWITCHOFF_STARTED: { // UL is being switched off and some module requests switch on! // Since the driver is required to maintain the order of requests // we perform the same actions as in the UL_OFF state onoff_ctl->l1_audio_ul_on2off_hold_time = L1_AUDIO_ON2OFF_UL_HOLD_TIME; onoff_ctl->l1_audio_ul_action = L1_AUDIO_TURN_ON; *state = L1_AUDIO_UL_SWITCHON_STARTED; onoff_ctl->l1_audio_ul_switched_on = FALSE; onoff_ctl->l1_audio_ul_switched_off = TRUE; #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; default: { // Invalid state put error trace here } break; } // end switch(l1_audio_ul_state) } // end if(l1_audio_switch_on_ul_req >= 1) else { // No module requires UL Audio path to be on switch(*state) { case L1_AUDIO_UL_OFF: { // UL audio path is off and all modules want it that way, do nothing } break; case L1_AUDIO_UL_SWITCHON_STARTED: { // UL audio path being switched on. Modules want it turned off! // Allow UL to be turned on, still if modules want it turned off // we will wait for ON2OFF hold time and turn it off if(onoff_ctl->l1_audio_ul_switched_on == TRUE) { onoff_ctl->l1_audio_ul_switched_off = FALSE; *state = L1_AUDIO_UL_ON; } #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_UL_ON: { // UL audio path is on and all modules want turn off. We wait // for the ON2OFF hold time and then actually turn it off if(onoff_ctl->l1_audio_ul_on2off_hold_time == 0) { onoff_ctl->l1_audio_ul_action = L1_AUDIO_TURN_OFF; *state = L1_AUDIO_UL_SWITCHOFF_STARTED; onoff_ctl->l1_audio_ul_switched_off = FALSE; onoff_ctl->l1_audio_ul_switched_on = TRUE; } else onoff_ctl->l1_audio_ul_on2off_hold_time--; #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_UL_SWITCHOFF_STARTED: { if(onoff_ctl->l1_audio_ul_switched_off == TRUE) { *state = L1_AUDIO_UL_OFF; } #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; default: { // Invalid state send error trace here } break; } // end switch(l1_audio_ul_state) } // end if(l1_audio_switch_on_ul_req >= 1)else #if (CODE_VERSION == SIMULATION) l1_audio_ul_onoff_simu_trace(); #else l1_audio_ul_onoff_trace(); #endif } // end l1s_audio_ul_onoff_manager() static void l1s_audio_dl_onoff_manager() { T_L1S_AUDIO_ONOFF_MANAGER *onoff_ctl = &(l1s.audio_on_off_ctl); UWORD8 *state = &l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE]; onoff_ctl->l1_audio_dl_action = L1_AUDIO_NO_ACTION; if(onoff_ctl->l1_audio_switch_on_dl_request >= 1) { // At least one module requires DL audio path to be on switch(*state) { case L1_AUDIO_DL_OFF: { // DL audio path is OFF and needs to be started onoff_ctl->l1_audio_dl_on2off_hold_time = L1_AUDIO_ON2OFF_DL_HOLD_TIME; onoff_ctl->l1_audio_dl_action = L1_AUDIO_TURN_ON; *state = L1_AUDIO_DL_SWITCHON_STARTED; onoff_ctl->l1_audio_dl_switched_on = FALSE; onoff_ctl->l1_audio_dl_switched_off = TRUE; } break; case L1_AUDIO_DL_SWITCHON_STARTED: { // DL audio path in the process of turning on // Check if it is turned on, if so change state to DL on if(onoff_ctl->l1_audio_dl_switched_on == TRUE) { onoff_ctl->l1_audio_dl_switched_off = FALSE; *state = L1_AUDIO_DL_ON; } #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_DL_ON: { /* OUTEN registers have been updated */ if(l1a_l1s_com.outen_cfg_task.command_requested != l1a_l1s_com.outen_cfg_task.command_commited) { #if (CODE_VERSION != SIMULATION) l1_outen_update(); #endif } // DL audio path is on and some module wants it to be so // Do nothing essentially except initialize the hold time onoff_ctl->l1_audio_dl_on2off_hold_time = L1_AUDIO_ON2OFF_DL_HOLD_TIME; #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_DL_SWITCHOFF_STARTED: { // DL is being switched off and some module requests switch on! // Since the driver is required to maintain the order of requests // we perform the same actions as in the DL_OFF state onoff_ctl->l1_audio_dl_on2off_hold_time = L1_AUDIO_ON2OFF_DL_HOLD_TIME; onoff_ctl->l1_audio_dl_action = L1_AUDIO_TURN_ON; *state = L1_AUDIO_DL_SWITCHON_STARTED; onoff_ctl->l1_audio_dl_switched_on = FALSE; onoff_ctl->l1_audio_dl_switched_off = TRUE; #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; default: { // Invalid state put error trace here } break; } // end switch(l1_audio_dl_state) } // end if(l1_audio_switch_on_dl_req >= 1) else { // No module requires DL Audio path to be on switch(*state) { case L1_AUDIO_DL_OFF: { // DL audio path is off and all modules want it that way, do nothing } break; case L1_AUDIO_DL_SWITCHON_STARTED: { // DL audio path being switched on. Modules want it turned off! // Allow DL to be turned on, still if modules want it turned off // we will wait for ON2OFF hold time and turn it off if(onoff_ctl->l1_audio_dl_switched_on == TRUE) { onoff_ctl->l1_audio_dl_switched_off = FALSE; *state = L1_AUDIO_DL_ON; } #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_DL_ON: { // DL audio path is on and all modules want turn off. We wait // for the ON2OFF hold time and then actually turn it off if(onoff_ctl->l1_audio_dl_on2off_hold_time == 0) { onoff_ctl->l1_audio_dl_action = L1_AUDIO_TURN_OFF; *state = L1_AUDIO_DL_SWITCHOFF_STARTED; onoff_ctl->l1_audio_dl_switched_off = FALSE; onoff_ctl->l1_audio_dl_switched_on = TRUE; } else onoff_ctl->l1_audio_dl_on2off_hold_time--; #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; case L1_AUDIO_DL_SWITCHOFF_STARTED: { if(onoff_ctl->l1_audio_dl_switched_off == TRUE) { *state = L1_AUDIO_DL_OFF; } #if(CODE_VERSION == NOT_SIMULATION) l1s.l1_audio_it_com = TRUE; #endif } break; default: { // Invalid state send error trace here } break; } // end switch(l1_audio_dl_state) } // end if(l1_audio_switch_on_dl_req >= 1)else #if (CODE_VERSION == SIMULATION) l1_audio_dl_onoff_simu_trace(); #else l1_audio_dl_onoff_trace(); #endif } // end l1s_audio_dl_onoff_manager() #if (CODE_VERSION == NOT_SIMULATION) void l1_audio_ul_onoff_trace() { static T_L1_AUDIO_UL_STATE prev_state = L1_INVALID; UWORD8 *curr_state = &l1s.audio_state[L1S_AUDIO_UL_ONOFF_STATE]; if(*curr_state != prev_state) { prev_state =(T_L1_AUDIO_UL_STATE) *curr_state; switch(prev_state) { case L1_AUDIO_UL_OFF: { //L1_trace_string("UL AUDIO OFF\r\n"); l1_trace_ul_audio_onoff(L1_AUDIO_UL_OFF); } break; case L1_AUDIO_UL_SWITCHON_STARTED: { l1_trace_ul_audio_onoff(L1_AUDIO_UL_SWITCHON_STARTED); } break; case L1_AUDIO_UL_ON: { l1_trace_ul_audio_onoff(L1_AUDIO_UL_ON); } break; case L1_AUDIO_UL_SWITCHOFF_STARTED: { l1_trace_ul_audio_onoff(L1_AUDIO_UL_SWITCHOFF_STARTED); } break; } // End switch(prev_state) } // end if(l1s.ul_state == prev_state) } void l1_audio_dl_onoff_trace() { static T_L1_AUDIO_DL_STATE prev_state = L1_DL_INVALID; UWORD8 *curr_state = &l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE]; if(*curr_state != prev_state) { prev_state = (T_L1_AUDIO_DL_STATE) *curr_state; switch(prev_state) { case L1_AUDIO_DL_OFF: { l1_trace_dl_audio_onoff(L1_AUDIO_DL_OFF); } break; case L1_AUDIO_DL_SWITCHON_STARTED: { l1_trace_dl_audio_onoff(L1_AUDIO_DL_SWITCHON_STARTED); } break; case L1_AUDIO_DL_ON: { l1_trace_dl_audio_onoff(L1_AUDIO_DL_ON); } break; case L1_AUDIO_DL_SWITCHOFF_STARTED: { l1_trace_dl_audio_onoff(L1_AUDIO_DL_SWITCHOFF_STARTED); } break; } // End switch(prev_state) } // end if(l1s.ul_state == prev_state) } #endif // CODE_VERSION == NOT_SIMULATION void l1_audio_abb_ul_on_callback(void) { l1s.audio_on_off_ctl.l1_audio_ul_switched_on = TRUE; } void l1_audio_abb_ul_off_callback(void) { l1s.audio_on_off_ctl.l1_audio_ul_switched_off = TRUE; } void l1_audio_abb_dl_on_callback(void) { l1_outen_update(); } void l1_audio_abb_dl_off_callback(void) { l1s.audio_on_off_ctl.l1_audio_dl_switched_off = TRUE; } void l1_audio_abb_ul_off_dl_off_callback(void) { l1s.audio_on_off_ctl.l1_audio_ul_switched_off = TRUE; l1s.audio_on_off_ctl.l1_audio_dl_switched_off = TRUE; } void l1_audio_abb_ul_off_dl_on_callback(void) { l1s.audio_on_off_ctl.l1_audio_ul_switched_off = TRUE; l1_outen_update(); } void l1_audio_abb_ul_on_dl_off_callback(void) { l1s.audio_on_off_ctl.l1_audio_ul_switched_on = TRUE; l1s.audio_on_off_ctl.l1_audio_dl_switched_off = TRUE; } void l1_audio_abb_ul_on_dl_on_callback(void) { l1s.audio_on_off_ctl.l1_audio_ul_switched_on = TRUE; l1_outen_update(); } void l1_audio_abb_outen_cfg_callback(UWORD8 argument) { (void)(argument); l1s.audio_on_off_ctl.l1_audio_dl_switched_on = TRUE; } #if (CODE_VERSION != SIMULATION) BspTwl3029_ReturnCode l1_outen_update(void) { BspTwl3029_ReturnCode returnVal = BSP_TWL3029_RETURN_CODE_FAILURE; UWORD16 count = 0; UINT8 triton_classD = 0; /* callback function info pointer */ BspTwl3029_I2C_Callback i2c_callback; BspTwl3029_I2C_CallbackPtr callbackPtr= &i2c_callback; /* I2C array */ Bsp_Twl3029_I2cTransReqArray i2cTransArray; Bsp_Twl3029_I2cTransReqArrayPtr i2cTransArrayPtr= &i2cTransArray; /* twl3029 I2C reg info struct */ BspTwl3029_I2C_RegisterInfo regInfo[11] ; BspTwl3029_I2C_RegisterInfo* regInfoPtr = regInfo; BspTwl3029_I2C_RegData tmpAudioHFTest1RegData=0; BspTwl3029_I2C_RegData tmpCtrl3RegData=0; l1a_l1s_com.outen_cfg_task.command_requested = l1a_l1s_com.outen_cfg_task.command_commited; bspTwl3029_Audio_getClassD_mode(&triton_classD); returnVal = BspTwl3029_I2c_shadowRegRead(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_AUDIO_CTRL3_OFFSET, &tmpCtrl3RegData); returnVal = BspTwl3029_I2c_shadowRegRead(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_AUDIO_HFTEST1_OFFSET, &tmpAudioHFTest1RegData); returnVal = BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_OUTEN1_OFFSET, l1a_l1s_com.outen_cfg_task.outen1, regInfoPtr++); count++; returnVal = BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_OUTEN2_OFFSET, l1a_l1s_com.outen_cfg_task.outen2, regInfoPtr++); count++; if(l1a_l1s_com.outen_cfg_task.classD == 0x01) // User wants to configure classD { if(triton_classD == 0x00) // User wants to switch on and Triton not configured for classD { BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_CKG_TESTUNLOCK_OFFSET, 0xb6, regInfoPtr++); count++; returnVal= BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_OUTEN3_OFFSET, l1a_l1s_com.outen_cfg_task.outen3, regInfoPtr++); count++; tmpCtrl3RegData |= 0x80; // AUDIO_CTRL3_SPKDIGON tmpAudioHFTest1RegData = 0x01; // AUDIO_HFTEST1_SPKALLZB BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_AUDIO_CTRL3_OFFSET, tmpCtrl3RegData, regInfoPtr++); count++; BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_AUDIO_HFTEST1_OFFSET, tmpAudioHFTest1RegData, regInfoPtr++); count++; } } else if(l1a_l1s_com.outen_cfg_task.classD == 0x00) { if(triton_classD != 0x00) // User wants no to classD and Triton configured for classD { tmpCtrl3RegData &= 0x7F; // AUDIO_CTRL3_SPKDIGON tmpAudioHFTest1RegData = 0x00; // AUDIO_HFTEST1_SPKALLZB BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_AUDIO_HFTEST1_OFFSET, tmpAudioHFTest1RegData, regInfoPtr++); count++; BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_AUDIO_CTRL3_OFFSET, tmpCtrl3RegData, regInfoPtr++); count++; returnVal= BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_OUTEN3_OFFSET, l1a_l1s_com.outen_cfg_task.outen3, regInfoPtr++); count++; BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD, BSP_TWL_3029_MAP_CKG_TESTUNLOCK_OFFSET, 0x00, regInfoPtr++); count++; } else // User no classD & Triton also no classD { returnVal= BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_OUTEN3_OFFSET, l1a_l1s_com.outen_cfg_task.outen3, regInfoPtr++); count++; returnVal = BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_OUTEN2_OFFSET, l1a_l1s_com.outen_cfg_task.outen2, regInfoPtr++); count++; returnVal= BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_OUTEN3_OFFSET, l1a_l1s_com.outen_cfg_task.outen3, regInfoPtr++); count++; } } returnVal= BspTwl3029_I2c_regQueWrite(BSP_TWL3029_I2C_AUD,BSP_TWL_3029_MAP_AUDIO_POPMAN_OFFSET, 0x00,regInfoPtr++); count++; callbackPtr->callbackFunc = l1_audio_abb_outen_cfg_callback; callbackPtr->callbackVal = 0; if (returnVal != BSP_TWL3029_RETURN_CODE_FAILURE) { regInfoPtr = regInfo; /* now request to I2C manager to write to Triton registers */ returnVal = BspTwl3029_I2c_regInfoSend(regInfo,count,callbackPtr, (BspI2c_TransactionRequest*)i2cTransArrayPtr); } return returnVal; } /* end function l1s_outen_update */ #endif #if (CODE_VERSION == SIMULATION) // This function is written to turn on the flag l1_audio_dl_switched_on during simulation signed char l1_outen_update(void) { l1s.audio_on_off_ctl.l1_audio_dl_switched_on = TRUE; } #endif #endif // L1_AUDIO_MCU_ONOFF // END Triton Audio ON/OFF Changes #if (KEYBEEP) /*-------------------------------------------------------*/ /* l1s_keybeep_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Keybeep L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_keybeep_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, WAIT_KEYBEEP_START = 2, WAIT_KEYBEEP_STOP = 3 #else WAIT_KEYBEEP_START = 1, WAIT_KEYBEEP_STOP = 2 #endif }; UWORD8 *state = &l1s.audio_state[L1S_KEYBEEP_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Triton Audio ON/OFF Changes #if(L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = WAIT_AUDIO_ON; #else // Start the DSP keybeep task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_KEYBEEP; *state = WAIT_KEYBEEP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Start the DSP keybeep task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_KEYBEEP; *state = WAIT_KEYBEEP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_KEYBEEP_START: { // the DSP acknowledges the L1S start request. if ((!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & B_KEYBEEP)) && (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_KEYBEEP)) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_KEYBEEP_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_KEYBEEP_STOP; } } break; case WAIT_KEYBEEP_STOP: { // the DSP is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_KEYBEEP)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_KEYBEEP_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } else // the MMI requests to stop the current keybeep if (l1a_l1s_com.keybeep_task.command.stop) { // Stop the DSP keybeep task l1s_dsp_com.dsp_ndb_ptr->d_dur_kb = 0; l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_KEYBEEP; // Disable the stop command l1a_l1s_com.keybeep_task.command.stop = FALSE; } } break; } // switch } #endif // KEYBEEP #if (TONE) /*-------------------------------------------------------*/ /* l1s_tone_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Tone L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_tone_manager(void) { enum states { IDLE = 0, // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF== 1) WAIT_AUDIO_ON = 1, WAIT_TONE_START = 2, WAIT_TONE_STOP = 3 #else WAIT_TONE_START = 1, WAIT_TONE_STOP = 2 #endif }; UWORD8 *state = &l1s.audio_state[L1S_TONE_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = WAIT_AUDIO_ON; #else // Start the DSP tone task #if ((DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // Linked to E2 melody // In case of WCP, there is a WCP variable at this address l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = NO_MELODY_SELECTED; #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init &= ~(B_MELO); l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_TONE; *state = WAIT_TONE_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Start the DSP tone task #if ((DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // Linked to E2 melody // In case of WCP, there is a WCP variable at this address l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = NO_MELODY_SELECTED; #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init &= ~(B_MELO); l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_TONE; *state = WAIT_TONE_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_TONE_START: { // the DSP acknowledges the L1S start request. if ((!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & B_TONE)) && (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_TONE)) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_TONE_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_TONE_STOP; } } break; case WAIT_TONE_STOP: { // the DSP is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_TONE)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // L1_AUDIO_MCU_ONOFF // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_TONE_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } else // the MMI requests to stop the current tone if (l1a_l1s_com.tone_task.command.stop) { // Stop the DSP tone task l1s_dsp_com.dsp_ndb_ptr->d_pe_rep = 0; l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_TONE; // Disable the stop command l1a_l1s_com.tone_task.command.stop = FALSE; } } break; } // switch } #endif // TONE #if (MELODY_E1) /*-------------------------------------------------------*/ /* l1s_melody0_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Melody 0 L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_melody0_manager(void) { enum states { M0_INACTIVE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) M0_WAIT_AUDIO_START = 1, M0_WAIT_DSP_START = 2, M0_WAIT_COUNTER_EQUAL_0 = 3, M0_WAIT_DESCRIPTION_START = 4, M0_WAIT_END_MELO = 5 #else M0_WAIT_DSP_START = 1, M0_WAIT_COUNTER_EQUAL_0 = 2, M0_WAIT_DESCRIPTION_START = 3, M0_WAIT_END_MELO = 4 #endif }; UWORD8 *state = &l1s.audio_state[L1S_MELODY0_STATE]; xSignalHeaderRec *conf_msg; UWORD8 i, load_size; UWORD16 melo_header[2], trash[4]; API *osc_used; switch(*state) { case M0_INACTIVE: { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = M0_WAIT_AUDIO_START; #else // Initialize the oscilators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody0.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Initialize the pointer to the buffer, the buffer size l1s.melody0.ptr_buf = l1a_l1s_com.melody0_task.parameters.ptr_buf; l1s.melody0.buffer_size = l1a_l1s_com.melody0_task.parameters.buffer_size; // Download the header of the first description of the melody l1s.melody0.error_id = copy_data_from_buffer (l1a_l1s_com.melody0_task.parameters.session_id, &l1s.melody0.buffer_size, (UWORD16 **)&l1s.melody0.ptr_buf, 1, &l1s.melody0.melody_header); // Initialize the counter with the first offset time: l1s.melody0.counter = ( ( Field(l1s.melody0.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; // Enable the oscillator used l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_used |= l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap; // Start the DSP melody task #if ((DSP==33) || (DSP == 34) || (DSP==35) || (DSP==36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // Linked to E2 melody // In case of WCP, there is a WCP variable at this address l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = MELODY_E1_SELECTED; #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (B_TONE | B_MELO); *state = M0_WAIT_DSP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case M0_WAIT_AUDIO_START: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Initialize the oscilators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody0.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Initialize the pointer to the buffer, the buffer size l1s.melody0.ptr_buf = l1a_l1s_com.melody0_task.parameters.ptr_buf; l1s.melody0.buffer_size = l1a_l1s_com.melody0_task.parameters.buffer_size; // Download the header of the first description of the melody l1s.melody0.error_id = copy_data_from_buffer (l1a_l1s_com.melody0_task.parameters.session_id, &l1s.melody0.buffer_size, (UWORD16 **)&l1s.melody0.ptr_buf, 1, &l1s.melody0.melody_header); // Initialize the counter with the first offset time: l1s.melody0.counter = ( ( Field(l1s.melody0.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; // Enable the oscillator used l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_used |= l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap; // Start the DSP melody task #if ((DSP==33) || (DSP == 34) || (DSP==35) || (DSP==36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // Linked to E2 melody // In case of WCP, there is a WCP variable at this address l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = MELODY_E1_SELECTED; #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (B_TONE | B_MELO); *state = M0_WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case M0_WAIT_DSP_START: { // The DSP is started if ( !(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & B_TONE) ) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_MELODY0_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = M0_WAIT_COUNTER_EQUAL_0; } } break; case M0_WAIT_COUNTER_EQUAL_0: { // The MMI resquests to stop the current melody 0. if (l1a_l1s_com.melody0_task.command.stop) { // Initialize the oscilators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody0.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Disable the loopback l1a_l1s_com.melody0_task.parameters.loopback = FALSE; // Disable the stop command l1a_l1s_com.melody0_task.command.stop = FALSE; *state = M0_WAIT_END_MELO; } else { // Decrease the download coundter l1s.melody0.counter--; // The description must be downloaded. if (l1s.melody0.counter == 0) { // Set the oscillator used in the following description l1s.melody0.oscillator_used_in_desc = Field(l1s.melody0.melody_header, SC_MELO_OSCILLATOR_USED_MASK, SC_MELO_OSCILLATOR_USED_SHIFT); l1s.melody0.oscillator_started = 0; // Download the new description for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (Field(l1s.melody0.oscillator_used_in_desc, (0x01<<i), i)) { // This oscillator description must be used. if (l1a_l1s_com.melody0_task.parameters.melody_to_oscillator[i] != SC_NUMBER_OSCILLATOR) { osc_used = l1s.melody0.oscillator[l1a_l1s_com.melody0_task.parameters.melody_to_oscillator[i]]; l1s.melody0.oscillator_started |= (0x01<<(l1a_l1s_com.melody0_task.parameters.melody_to_oscillator[i])); } else // The oscillator description isn't used and put to the "trash" { osc_used = trash; } // Download the two first words of the oscillator description l1s.melody0.error_id = copy_data_from_buffer (l1a_l1s_com.melody0_task.parameters.session_id, &l1s.melody0.buffer_size, (UWORD16 **)&l1s.melody0.ptr_buf, 2, osc_used); load_size = 0; if (Field(*(osc_used+1), SC_MELO_LOAD1_MASK, SC_MELO_LOAD1_SHIFT)) load_size++; if (Field(*(osc_used+1), SC_MELO_LOAD2_MASK, SC_MELO_LOAD2_SHIFT)) load_size++; // Download the next word(s) of the oscillator description l1s.melody0.error_id = copy_data_from_buffer (l1a_l1s_com.melody0_task.parameters.session_id, &l1s.melody0.buffer_size, (UWORD16 **)&l1s.melody0.ptr_buf, load_size, osc_used+2); // Enable this new description *osc_used |= 1; } } *state = M0_WAIT_DESCRIPTION_START; } } } break; case M0_WAIT_DESCRIPTION_START: { // The new description is started or no oscillator of the description was allocated. if ((l1s.melody0.oscillator_started & l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_active) || (l1s.melody0.oscillator_started == 0) ) { // Download the header of the next description of the melody l1s.melody0.error_id = copy_data_from_buffer (l1a_l1s_com.melody0_task.parameters.session_id, &l1s.melody0.buffer_size, (UWORD16 **)&l1s.melody0.ptr_buf, 1, &l1s.melody0.melody_header); // Is it the end of the melody? if (l1s.melody0.melody_header == 0x0000) { *state = M0_WAIT_END_MELO; #if 0 /* FreeCalypso TCS211 reconstruction */ // Header is wrong - L1 needs a forcible stop here #if (CODE_VERSION == SIMULATION) // l1a_l1s_com.melody1_task.command.stop = TRUE; #else l1a_l1s_com.melody1_task.command.stop = TRUE; #endif #endif } else { // Initialize the counter with the next offset time: l1s.melody0.counter = ( ( Field(l1s.melody0.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; *state = M0_WAIT_COUNTER_EQUAL_0; } } } break; case M0_WAIT_END_MELO: { if (l1a_l1s_com.melody0_task.command.stop) { // Initialize the oscillators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody0.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Disable the loopback l1a_l1s_com.melody0_task.parameters.loopback = FALSE; // Disable the stop command l1a_l1s_com.melody0_task.command.stop = FALSE; *state = M0_WAIT_END_MELO; } else // All oscillators used are stopped. if (!( l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap & l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_active)) { // The melody is in loopback mode? if (l1a_l1s_com.melody0_task.parameters.loopback) { // Reset the buffer description #if (OP_RIV_AUDIO == 0) l1s.melody0.ptr_buf = NULL; #endif l1s.melody0.buffer_size = 0; l1s.melody0.error_id = Cust_get_pointer((UWORD16 **)&l1s.melody0.ptr_buf, &l1s.melody0.buffer_size, l1a_l1s_com.melody0_task.parameters.session_id); // Download the 2 first words of the melody l1s.melody0.error_id = copy_data_from_buffer (l1a_l1s_com.melody0_task.parameters.session_id, &l1s.melody0.buffer_size, (UWORD16 **)&l1s.melody0.ptr_buf, 2, (UWORD16 *)&melo_header); // Save the header of the first melody score description l1s.melody0.melody_header = melo_header[1]; // Initialize the counter with the first offset time: l1s.melody0.counter = ( ( Field(l1s.melody0.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; *state = M0_WAIT_COUNTER_EQUAL_0; } else { // Disable the oscillator dedicated to this melody l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_used &= ~(l1a_l1s_com.melody0_task.parameters.oscillator_used_bitmap); // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_MELODY0_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = M0_INACTIVE; } } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_melody1_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Melody 1 L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_melody1_manager(void) { enum states { M1_INACTIVE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) M1_WAIT_AUDIO_START = 1, M1_WAIT_DSP_START = 2, M1_WAIT_COUNTER_EQUAL_0 = 3, M1_WAIT_DESCRIPTION_START = 4, M1_WAIT_END_MELO = 5 #else M1_WAIT_DSP_START = 1, M1_WAIT_COUNTER_EQUAL_0 = 2, M1_WAIT_DESCRIPTION_START = 3, M1_WAIT_END_MELO = 4 #endif }; UWORD8 *state = &l1s.audio_state[L1S_MELODY1_STATE]; xSignalHeaderRec *conf_msg; UWORD8 i, load_size; UWORD16 melo_header[2], trash[4]; API *osc_used; switch(*state) { case M1_INACTIVE: { #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = M1_WAIT_AUDIO_START; #else // Initialize the oscilators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody1.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Initialize the pointer to the buffer, the buffer size l1s.melody1.ptr_buf = l1a_l1s_com.melody1_task.parameters.ptr_buf; l1s.melody1.buffer_size = l1a_l1s_com.melody1_task.parameters.buffer_size; // Download the header of the first description of the melody l1s.melody1.error_id = copy_data_from_buffer (l1a_l1s_com.melody1_task.parameters.session_id, &l1s.melody1.buffer_size, (UWORD16 **)&l1s.melody1.ptr_buf, 1, &l1s.melody1.melody_header); // Initialize the counter with the first offset time: l1s.melody1.counter = ( ( Field(l1s.melody1.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; // Enable the oscillator used l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_used |= l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap; // Start the DSP melody task #if ((DSP==33) || (DSP == 34) || (DSP==35) || (DSP==36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // Linked to E2 melody // In case of WCP, there is a WCP variable at this address l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = MELODY_E1_SELECTED; #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (B_TONE | B_MELO); *state = M1_WAIT_DSP_START; #endif } break; #if (L1_AUDIO_MCU_ONOFF == 1) case M1_WAIT_AUDIO_START: { if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Initialize the oscilators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody1.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Initialize the pointer to the buffer, the buffer size l1s.melody1.ptr_buf = l1a_l1s_com.melody1_task.parameters.ptr_buf; l1s.melody1.buffer_size = l1a_l1s_com.melody1_task.parameters.buffer_size; // Download the header of the first description of the melody l1s.melody1.error_id = copy_data_from_buffer (l1a_l1s_com.melody1_task.parameters.session_id, &l1s.melody1.buffer_size, (UWORD16 **)&l1s.melody1.ptr_buf, 1, &l1s.melody1.melody_header); // Initialize the counter with the first offset time: l1s.melody1.counter = ( ( Field(l1s.melody1.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; // Enable the oscillator used l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_used |= l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap; // Start the DSP melody task #if ((DSP==33) || (DSP == 34) || (DSP==35) || (DSP==36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // Linked to E2 melody // In case of WCP, there is a WCP variable at this address l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = MELODY_E1_SELECTED; #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (B_TONE | B_MELO); *state = M1_WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case M1_WAIT_DSP_START: { // The DSP is started if ( !(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & B_TONE) ) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_MELODY1_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = M1_WAIT_COUNTER_EQUAL_0; } } break; case M1_WAIT_COUNTER_EQUAL_0: { // The MMI resquests to stop the current melody 1. if (l1a_l1s_com.melody1_task.command.stop) { // Initialize the oscilators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody1.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Disable the loopback l1a_l1s_com.melody1_task.parameters.loopback = FALSE; // Disable the stop command l1a_l1s_com.melody1_task.command.stop = FALSE; *state = M1_WAIT_END_MELO; } else { // Decrease the download coundter l1s.melody1.counter--; // The description must be downloaded. if (l1s.melody1.counter == 0) { // Set the oscillator used in the following description l1s.melody1.oscillator_used_in_desc = Field(l1s.melody1.melody_header, SC_MELO_OSCILLATOR_USED_MASK, SC_MELO_OSCILLATOR_USED_SHIFT); l1s.melody1.oscillator_started = 0; // Download the new description for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (Field(l1s.melody1.oscillator_used_in_desc, (0x01<<i), i)) { // This oscillator description must be used. if (l1a_l1s_com.melody1_task.parameters.melody_to_oscillator[i] != SC_NUMBER_OSCILLATOR) { osc_used = l1s.melody1.oscillator[l1a_l1s_com.melody1_task.parameters.melody_to_oscillator[i]]; l1s.melody1.oscillator_started |= (0x01<<(l1a_l1s_com.melody1_task.parameters.melody_to_oscillator[i])); } else // The oscillator description isn't used and put to the "trash" { osc_used = trash; } // Download the two first words of the oscillator description l1s.melody1.error_id = copy_data_from_buffer (l1a_l1s_com.melody1_task.parameters.session_id, &l1s.melody1.buffer_size, (UWORD16 **)&l1s.melody1.ptr_buf, 2, osc_used); load_size = 0; if (Field(*(osc_used+1), SC_MELO_LOAD1_MASK, SC_MELO_LOAD1_SHIFT)) load_size++; if (Field(*(osc_used+1), SC_MELO_LOAD2_MASK, SC_MELO_LOAD2_SHIFT)) load_size++; // Download the next word(s) of the oscillator description l1s.melody1.error_id = copy_data_from_buffer (l1a_l1s_com.melody1_task.parameters.session_id, &l1s.melody1.buffer_size, (UWORD16 **)&l1s.melody1.ptr_buf, load_size, osc_used+2); // Enable this new description *osc_used |= 1; } } *state = M1_WAIT_DESCRIPTION_START; } } } break; case M1_WAIT_DESCRIPTION_START: { // The new description is started or no oscillator of the description was allocated. if ((l1s.melody1.oscillator_started & l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_active) || (l1s.melody1.oscillator_started == 0) ) { // Download the header of the next description of the melody l1s.melody1.error_id = copy_data_from_buffer (l1a_l1s_com.melody1_task.parameters.session_id, &l1s.melody1.buffer_size, (UWORD16 **)&l1s.melody1.ptr_buf, 1, &l1s.melody1.melody_header); // Is it the end of the melody? if (l1s.melody1.melody_header == 0x0000) { *state = M1_WAIT_END_MELO; #if 0 /* FreeCalypso TCS211 reconstruction */ /* Header is wrong - L1 needs a forcible stop here */ #if (CODE_VERSION == SIMULATION) // l1a_l1s_com.melody1_task.command.stop = TRUE; #else l1a_l1s_com.melody1_task.command.stop = TRUE; #endif #endif } else { // Initialize the counter with the next offset time: l1s.melody1.counter = ( ( Field(l1s.melody1.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; *state = M1_WAIT_COUNTER_EQUAL_0; } } } break; case M1_WAIT_END_MELO: { if (l1a_l1s_com.melody1_task.command.stop) { // Initialize the oscillators used: for (i=0; i<SC_NUMBER_OSCILLATOR; i++) { if (l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap & (0x1<<i)) *(l1s.melody1.oscillator[i]) = SC_END_OSCILLATOR_MASK; } // Disable the loopback l1a_l1s_com.melody1_task.parameters.loopback = FALSE; // Disable the stop command l1a_l1s_com.melody1_task.command.stop = FALSE; *state = M1_WAIT_END_MELO; } else // All oscillators used are stopped. if (!( l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap & l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_active)) { // The melody is in loopback mode? if (l1a_l1s_com.melody1_task.parameters.loopback) { // Reset the pointer to the buffer #if (OP_RIV_AUDIO == 0) l1s.melody1.ptr_buf = NULL; #endif l1s.melody1.buffer_size = 0; l1s.melody1.error_id = Cust_get_pointer((UWORD16 **)&l1s.melody1.ptr_buf, &l1s.melody1.buffer_size, l1a_l1s_com.melody1_task.parameters.session_id); // Download the 2 first words of the first description of the melody l1s.melody1.error_id = copy_data_from_buffer (l1a_l1s_com.melody1_task.parameters.session_id, &l1s.melody1.buffer_size, (UWORD16 **)&l1s.melody1.ptr_buf, 2, (UWORD16 *)&melo_header); // Save the header of the first melody score description l1s.melody1.melody_header = melo_header[1]; // Initialize the counter with the first offset time: l1s.melody1.counter = ( ( Field(l1s.melody1.melody_header, SC_MELO_TIME_OFFSET_MASK, SC_MELO_TIME_OFFSET_SHIFT) ) * SC_MELO_DOWNLOAD_TIME_UNIT ) - 1; *state = M1_WAIT_COUNTER_EQUAL_0; } else { // Disable the oscillator dedicated to this melody l1s_dsp_com.dsp_ndb_ptr->d_melo_osc_used &= ~(l1a_l1s_com.melody1_task.parameters.oscillator_used_bitmap); #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_MELODY1_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = M1_INACTIVE; } } } break; } // switch } #endif // MELODY_E1 #if (VOICE_MEMO) /*-------------------------------------------------------*/ /* l1s_vm_play_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Voice memo playing L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_vm_play_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, WAIT_DSP_START = 2, WAIT_DSP_REQUEST = 3, WAIT_DSP_STOP = 4 #else WAIT_DSP_START = 1, WAIT_DSP_REQUEST = 2, WAIT_DSP_STOP = 3 #endif }; UWORD8 *state = &l1s.audio_state[L1S_VM_PLAY_STATE]; xSignalHeaderRec *conf_msg; UWORD16 sample_header; switch(*state) { case IDLE: { #if (L1_AUDIO_MCU_ONOFF == 1) // Triton Audio ON/OFF Changes l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = WAIT_AUDIO_ON; #else // Initialize the buffer parameters l1s.voicememo.play.ptr_buf = NULL; l1s.voicememo.play.buffer_size = 0; l1s.voicememo.play.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo.play.ptr_buf, &l1s.voicememo.play.buffer_size, l1a_l1s_com.voicememo_task.play.parameters.session_id); // Start the voice memo playing DSP task #if ((DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // use TCH/FS vocoder l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VM_VOCODER_SELECT); #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_PLAY_START; // Determine which a_du buffer is currently used l1s.voicememo.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } // Download the header of the new speech sample l1s.voicememo.play.error_id = copy_data_from_buffer (l1a_l1s_com.voicememo_task.play.parameters.session_id, &l1s.voicememo.play.buffer_size, (UWORD16 **)&l1s.voicememo.play.ptr_buf, 1, &sample_header); // Download the data to the a_du_x buffer if the sample isn't a noise sample. if (sample_header & B_VM_SPEECH) { l1s.voicememo.play.error_id = copy_data_from_buffer (l1a_l1s_com.voicememo_task.play.parameters.session_id, &l1s.voicememo.play.buffer_size, (UWORD16 **)&l1s.voicememo.play.ptr_buf, SC_VM_SPEECH_SAMPLE-1, l1s.voicememo.play.a_du_x+1); } // Send the header to the DSP *l1s.voicememo.play.a_du_x = sample_header; *state = WAIT_DSP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Initialize the buffer parameters l1s.voicememo.play.ptr_buf = NULL; l1s.voicememo.play.buffer_size = 0; l1s.voicememo.play.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo.play.ptr_buf, &l1s.voicememo.play.buffer_size, l1a_l1s_com.voicememo_task.play.parameters.session_id); // Start the voice memo playing DSP task #if (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39) // use TCH/FS vocoder l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VM_VOCODER_SELECT); #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_PLAY_START; // Determine which a_du buffer is currently used l1s.voicememo.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } // Download the header of the new speech sample l1s.voicememo.play.error_id = copy_data_from_buffer (l1a_l1s_com.voicememo_task.play.parameters.session_id, &l1s.voicememo.play.buffer_size, (UWORD16 **)&l1s.voicememo.play.ptr_buf, 1, &sample_header); // Download the data to the a_du_x buffer if the sample isn't a noise sample. if (sample_header & B_VM_SPEECH) { l1s.voicememo.play.error_id = copy_data_from_buffer (l1a_l1s_com.voicememo_task.play.parameters.session_id, &l1s.voicememo.play.buffer_size, (UWORD16 **)&l1s.voicememo.play.ptr_buf, SC_VM_SPEECH_SAMPLE-1, l1s.voicememo.play.a_du_x+1); } // Send the header to the DSP *l1s.voicememo.play.a_du_x = sample_header; *state = WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_DSP_START: { // The DSP task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_PLAY_ON_GOING) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_PLAY_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_REQUEST; } } break; case WAIT_DSP_REQUEST: { // The MMI requests to stop the voice memorization playing task if (l1a_l1s_com.voicememo_task.play.command.stop) { // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_PLAY_STOP; *state = WAIT_DSP_STOP; } else // The DSP needs a new block { // Determine which a_du buffer is currently used l1s.voicememo.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } if (!(*(l1s.voicememo.play.a_du_x) & B_BLOCK_READY)) { // Download the header of the new speech sample l1s.voicememo.play.error_id = copy_data_from_buffer (l1a_l1s_com.voicememo_task.play.parameters.session_id, &l1s.voicememo.play.buffer_size, (UWORD16 **)&l1s.voicememo.play.ptr_buf, 1, &sample_header); // Is it the end of the voice memo data buffer? if ( sample_header == SC_VM_END_MASK ) { // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_PLAY_STOP; *state = WAIT_DSP_STOP; } else { // Download the data to the a_du_x buffer if the sample isn't a noise sample. if (sample_header & B_VM_SPEECH) { l1s.voicememo.play.error_id = copy_data_from_buffer (l1a_l1s_com.voicememo_task.play.parameters.session_id, &l1s.voicememo.play.buffer_size, (UWORD16 **)&l1s.voicememo.play.ptr_buf, SC_VM_SPEECH_SAMPLE-1, l1s.voicememo.play.a_du_x+1); } // Send the header to the DSP *l1s.voicememo.play.a_du_x = sample_header; } } } } break; case WAIT_DSP_STOP: { // The DSP voice memorization playing task is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_PLAY_ON_GOING)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // L1_AUDIO_MCU_ONOFF // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_PLAY_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_vm_record_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Voice memo recoding L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_vm_record_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, WAIT_DSP_START = 2, WAIT_DSP_SAMPLE = 3, WAIT_DSP_STOP = 4 #else WAIT_DSP_START = 1, WAIT_DSP_SAMPLE = 2, WAIT_DSP_STOP = 3 #endif // L1_AUDIO_MCU_ONOFF }; UWORD8 *state = &l1s.audio_state[L1S_VM_RECORD_STATE]; xSignalHeaderRec *conf_msg; UWORD8 size; UWORD16 data; switch(*state) { case IDLE: { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request++; *state = WAIT_AUDIO_ON; #else // Initialize the buffer parameters l1s.voicememo.record.ptr_buf = NULL; l1s.voicememo.record.buffer_size = 0; l1s.voicememo.record.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo.record.ptr_buf, &l1s.voicememo.record.buffer_size, l1a_l1s_com.voicememo_task.record.parameters.session_id); // Initialize the size of the Voice memo to record l1s.voicememo.record.recorded_size = 0; // Initialize the DTX mode if (l1a_l1s_com.voicememo_task.record.parameters.dtx) l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VOICE_MEMO_DTX; else l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VOICE_MEMO_DTX); #if ((DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // use TCH/FS vocoder l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VM_VOCODER_SELECT); #endif // Start the voice memo recording DSP task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_RECORD_START; *state = WAIT_DSP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_UL_ONOFF_STATE] == L1_AUDIO_UL_ON)) { // Initialize the buffer parameters l1s.voicememo.record.ptr_buf = NULL; l1s.voicememo.record.buffer_size = 0; l1s.voicememo.record.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo.record.ptr_buf, &l1s.voicememo.record.buffer_size, l1a_l1s_com.voicememo_task.record.parameters.session_id); // Initialize the size of the Voice memo to record l1s.voicememo.record.recorded_size = 0; // Initialize the DTX mode if (l1a_l1s_com.voicememo_task.record.parameters.dtx) l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VOICE_MEMO_DTX; else l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VOICE_MEMO_DTX); #if (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39) // use TCH/FS vocoder l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VM_VOCODER_SELECT); #endif // Start the voice memo recording DSP task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_RECORD_START; *state = WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_DSP_START: { // The DSP task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_RECORD_ON_GOING) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_RECORD_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_SAMPLE; } } break; case WAIT_DSP_SAMPLE: { // The MMI requests to stop the voice memorization recording task if (l1a_l1s_com.voicememo_task.record.command.stop) { // Write the end mask at the end of the voice data RAM buffer data = SC_VM_END_MASK; l1s.voicememo.record.error_id = copy_data_to_buffer (l1a_l1s_com.voicememo_task.record.parameters.session_id, &l1s.voicememo.record.buffer_size, (UWORD16 **)&l1s.voicememo.record.ptr_buf, 1, &data); // Increase the recorded size l1s.voicememo.record.recorded_size++; // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_RECORD_STOP; // Clear the a_du_x header: *(l1s.voicememo.record.a_du_x) = 0; *state = WAIT_DSP_STOP; } else // The DSP needs a new block { // Determine which a_du buffer is currently used l1s.voicememo.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } // The DSP sends a new block? if ( (*(l1s.voicememo.record.a_du_x)) & B_BLOCK_READY ) { // Check if the block contains a sample of noise or speech if ( (*(l1s.voicememo.record.a_du_x)) & B_VM_SPEECH ) size = SC_VM_SPEECH_SAMPLE; else size = SC_VM_NOISE_SAMPLE; // The maximum allocated size is reached? if ( (l1s.voicememo.record.recorded_size+size+1) <= l1a_l1s_com.voicememo_task.record.parameters.maximum_size) { // Download the data to the a_du_x buffer. l1s.voicememo.record.error_id = copy_data_to_buffer (l1a_l1s_com.voicememo_task.record.parameters.session_id, &l1s.voicememo.record.buffer_size, (UWORD16 **)&l1s.voicememo.record.ptr_buf, size, l1s.voicememo.record.a_du_x); // Increase the recorded size l1s.voicememo.record.recorded_size += size; // Clear the a_du_x header: *(l1s.voicememo.record.a_du_x) = 0; } else { // Write the end mask at the end of the voice data RAM buffer data = SC_VM_END_MASK; l1s.voicememo.record.error_id = copy_data_to_buffer (l1a_l1s_com.voicememo_task.record.parameters.session_id, &l1s.voicememo.record.buffer_size, (UWORD16 **)&l1s.voicememo.record.ptr_buf, 1, &data); // Increase the recorded size l1s.voicememo.record.recorded_size++; // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_RECORD_STOP; // Clear the a_du_x header: *(l1s.voicememo.record.a_du_x) = 0; *state = WAIT_DSP_STOP; } } } } break; case WAIT_DSP_STOP: { // The DSP voice memorization playing task is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_RECORD_ON_GOING)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request--; #endif // L1_AUDIO_MCU_ONOFF // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_VM_RECORD_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_RECORD_STOP_CON; //Fill the message ((T_L1_VM_RECORD_CON *)(conf_msg->SigP))->recorded_size = l1s.voicememo.record.recorded_size; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_tone_ul_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : tone uplink L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_tone_ul_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, WAIT_DEDIC_SPEECH_MODE = 2, WAIT_TONE_UL_START = 3, WAIT_TONE_UL_STOP = 4 #else WAIT_DEDIC_SPEECH_MODE = 1, WAIT_TONE_UL_START = 2, WAIT_TONE_UL_STOP = 3 #endif }; UWORD8 *state = &l1s.audio_state[L1S_TONE_UL_STATE]; switch(*state) { case IDLE: { #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = WAIT_AUDIO_ON; #else // Start the tone uplink task if (l1a_l1s_com.voicememo_task.record.tone_ul.start) { // Set the tone uplink option: l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_TONE_UL; } *state = WAIT_DEDIC_SPEECH_MODE; #endif } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Start the tone uplink task if (l1a_l1s_com.voicememo_task.record.tone_ul.start) { // Set the tone uplink option: l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_TONE_UL; } *state = WAIT_DEDIC_SPEECH_MODE; } } break; #endif // (L1_AUDIO_MCU_ONOFF == 1) case WAIT_DEDIC_SPEECH_MODE: { // The voice memorization task is stopping: if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & B_VM_TONE_UL)) { // Reset the start command l1a_l1s_com.voicememo_task.record.tone_ul.start = FALSE; #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // L1_AUDIO_MCU_ONOFF *state = IDLE; } else // Dedicated mode speech start? if (l1a_l1s_com.dedic_set.aset != NULL) { #if (AMR == 1) if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_HS_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_EFR_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_FS_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AFS_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AHS_MODE) ) #else if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_HS_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_EFR_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_FS_MODE) ) #endif { // Start the tone uplink DSP task #if ((DSP==33) || (DSP == 34) || (DSP==35) || (DSP==36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // Linked to E2 melody // In case of WCP, there is a WCP variable at this address l1s_dsp_com.dsp_ndb_ptr->d_melody_selection = NO_MELODY_SELECTED; #endif l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init &= ~(B_MELO); l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_TONE; *state = WAIT_TONE_UL_START; } } } break; case WAIT_TONE_UL_START: { // the tone uplink task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_TONE) { *state = WAIT_TONE_UL_STOP; } } break; case WAIT_TONE_UL_STOP: { // The voice memorization task is stopping: if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & B_VM_TONE_UL)) { // Stop the tone uplink task: l1s_dsp_com.dsp_ndb_ptr->d_pe_rep = 0; l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_TONE; #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // L1_AUDIO_MCU_ONOFF *state = IDLE; } else // The tone uplink task is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_TONE)) { #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // L1_AUDIO_MCU_ONOFF *state = IDLE; } } break; } // switch } #endif // VOICE_MEMO #if (L1_PCM_EXTRACTION) /*-------------------------------------------------------*/ /* l1s_pcm_download_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : PCM download L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_pcm_download_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, #endif WAIT_DSP_START = 2, WAIT_DSP_REQUEST = 3, WAIT_DSP_STOP = 4 }; UWORD8 *state = &l1s.audio_state[L1S_PCM_DOWNLOAD_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { #if (L1_AUDIO_MCU_ONOFF == 1) // Triton Audio ON/OFF Changes l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = WAIT_AUDIO_ON; #else // Initialize the buffer parameters l1s.pcm.download.ptr_buf = NULL; l1s.pcm.download.buffer_size = 0; l1s.pcm.download.error_id = Cust_get_pointer((UWORD16 **)&l1s.pcm.download.ptr_buf, &l1s.pcm.download.buffer_size, l1a_l1s_com.pcm_task.download.parameters.session_id); // Download the PCM samples l1s.pcm.download.error_id = copy_data_from_buffer (l1a_l1s_com.pcm_task.download.parameters.session_id, &l1s.pcm.download.buffer_size, (UWORD16 **)&l1s.pcm.download.ptr_buf, SC_PCM_DOWNLOAD_SAMPLE, l1s_dsp_com.dsp_ndb_ptr->a_pcm_api_download); // Increase the downloaded size of PCM samples l1s.pcm.download.downloaded_size = SC_PCM_DOWNLOAD_SAMPLE; l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_download |= (B_PCM_DOWNLOAD_READY); l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_DOWNLOAD_START; *state = WAIT_DSP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Initialize the buffer parameters l1s.pcm.download.ptr_buf = NULL; l1s.pcm.download.buffer_size = 0; l1s.pcm.download.error_id = Cust_get_pointer((UWORD16 **)&l1s.pcm.download.ptr_buf, &l1s.pcm.download.buffer_size, l1a_l1s_com.pcm_task.download.parameters.session_id); // Download the PCM samples l1s.pcm.download.error_id = copy_data_from_buffer (l1a_l1s_com.pcm_task.download.parameters.session_id, &l1s.pcm.download.buffer_size, (UWORD16 **)&l1s.pcm.download.ptr_buf, SC_PCM_DOWNLOAD_SAMPLE, l1s_dsp_com.dsp_ndb_ptr->a_pcm_api_download); // Increase the downloaded size of PCM samples l1s.pcm.download.downloaded_size = SC_PCM_DOWNLOAD_SAMPLE; l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_download |= (B_PCM_DOWNLOAD_READY); l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_DOWNLOAD_START; *state = WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_DSP_START: { // The DSP task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_PCM_DOWNLOAD_ON_GOING) { conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_PCM_DOWNLOAD_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_REQUEST; } } break; case WAIT_DSP_REQUEST: { if (l1a_l1s_com.pcm_task.download.command.stop) { // Stop the DSP PCM playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_DOWNLOAD_STOP; l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_download = 0; *state = WAIT_DSP_STOP; } else { // B_PCM_DOWNLOAD_READY is reset if DSP is ready to get new sample if (!(l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_download & B_PCM_DOWNLOAD_READY)) { if(l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_error & B_PCM_DOWNLOAD_ERROR) { #if (TRACE_TYPE==1) || (TRACE_TYPE==4) l1_trace_PCM_DSP_error(); #endif } /* end if DSP error check - underflow */ if ((l1s.pcm.download.downloaded_size + SC_PCM_DOWNLOAD_SAMPLE) <= l1a_l1s_com.pcm_task.download.parameters.maximum_size) { // Download the data to the a_pcm_api_download buffer l1s.pcm.download.error_id = copy_data_from_buffer (l1a_l1s_com.pcm_task.download.parameters.session_id, &l1s.pcm.download.buffer_size, (UWORD16 **)&l1s.pcm.download.ptr_buf, SC_PCM_DOWNLOAD_SAMPLE, l1s_dsp_com.dsp_ndb_ptr->a_pcm_api_download); // Increase the downloaded size l1s.pcm.download.downloaded_size += SC_PCM_DOWNLOAD_SAMPLE; l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_download |= (B_PCM_DOWNLOAD_READY); } /* end if download speech sample*/ else { // Stop the DSP PCM playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_DOWNLOAD_STOP; l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_download = 0; *state = WAIT_DSP_STOP; } /* end else - download buffer size reached */ } /* end if DSP requested new block */ } /* end else not download task stop command */ } break; case WAIT_DSP_STOP: { if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_PCM_DOWNLOAD_ON_GOING)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // L1_AUDIO_MCU_ONOFF conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_PCM_DOWNLOAD_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_pcm_upload_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : PCM uploading manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_pcm_upload_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, #endif // L1_AUDIO_MCU_ONOFF WAIT_DSP_START = 2, WAIT_DSP_SAMPLE = 3, WAIT_DSP_STOP = 4 }; UWORD8 *state = &l1s.audio_state[L1S_PCM_UPLOAD_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request++; *state = WAIT_AUDIO_ON; #else // Initialize the buffer parameters l1s.pcm.upload.ptr_buf = NULL; l1s.pcm.upload.buffer_size = 0; l1s.pcm.upload.error_id = Cust_get_pointer((UWORD16 **)&l1s.pcm.upload.ptr_buf, &l1s.pcm.upload.buffer_size, l1a_l1s_com.pcm_task.upload.parameters.session_id); // Initialize the size of the PCM upload l1s.pcm.upload.uploaded_size = 0; // Start the PCM recording DSP task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_UPLOAD_START; *state = WAIT_DSP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_UL_ONOFF_STATE] == L1_AUDIO_UL_ON)) { // Initialize the buffer parameters l1s.pcm.upload.ptr_buf = NULL; l1s.pcm.upload.buffer_size = 0; l1s.pcm.upload.error_id = Cust_get_pointer((UWORD16 **)&l1s.pcm.upload.ptr_buf, &l1s.pcm.upload.buffer_size, l1a_l1s_com.pcm_task.upload.parameters.session_id); // Initialize the size of the PCM upload l1s.pcm.upload.uploaded_size = 0; // Start the PCM recording DSP task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_UPLOAD_START; *state = WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_DSP_START: { // The DSP task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_PCM_UPLOAD_ON_GOING) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_PCM_UPLOAD_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_SAMPLE; } } break; case WAIT_DSP_SAMPLE: { // The MMI requests to stop the PCM recording task if (l1a_l1s_com.pcm_task.upload.command.stop) { // Stop the DSP PCM recording task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_UPLOAD_STOP; l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_upload = 0; *state = WAIT_DSP_STOP; } else // The DSP needs a new block { // The DSP sends a new block? if (l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_upload & B_PCM_UPLOAD_READY ) { if(l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_error & B_PCM_UPLOAD_ERROR) { #if (TRACE_TYPE==1) || (TRACE_TYPE==4) l1_trace_PCM_DSP_error(); #endif } /* end if DSP error check - overflow */ if ((l1s.pcm.upload.uploaded_size + SC_PCM_UPLOAD_SAMPLE) <= l1a_l1s_com.pcm_task.upload.parameters.maximum_size) { // Download the data to the a_pcm_api_upload buffer. l1s.pcm.upload.error_id = copy_data_to_buffer (l1a_l1s_com.pcm_task.upload.parameters.session_id, &l1s.pcm.upload.buffer_size, (UWORD16 **)&l1s.pcm.upload.ptr_buf, SC_PCM_UPLOAD_SAMPLE, l1s_dsp_com.dsp_ndb_ptr->a_pcm_api_upload); // Increase the recorded size l1s.pcm.upload.uploaded_size += SC_PCM_UPLOAD_SAMPLE; // Clear the d_pcm_api_upload header l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_upload &= (~B_PCM_UPLOAD_READY); } else { // Stop the DSP PCM recording task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_PCM_UPLOAD_STOP; l1s_dsp_com.dsp_ndb_ptr->d_pcm_api_upload = 0; *state = WAIT_DSP_STOP; } /* end else maximum uplaod size reached */ } /* end if DSP sends a new block */ } /* end else */ } break; case WAIT_DSP_STOP: { // The DSP PCM upload task is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_PCM_UPLOAD_ON_GOING)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request--; #endif // L1_AUDIO_MCU_ONOFF // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_PCM_UPLOAD_STOP_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_PCM_UPLOAD_STOP_CON; //Fill the message ((T_L1_PCM_UPLOAD_STOP_CON *)(conf_msg->SigP))->uploaded_size = l1s.pcm.upload.uploaded_size; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif /* L1_PCM_EXTRACTION */ #if (L1_VOICE_MEMO_AMR) /*-------------------------------------------------------*/ /* l1s_vm_amr_play_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Voice memo amr playing L1S manager task.*/ /* */ /*-------------------------------------------------------*/ void l1s_vm_amr_play_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, WAIT_DSP_START = 2, WAIT_DSP_REQUEST = 3, WAIT_DSP_STOP = 4 #else WAIT_DSP_START = 1, WAIT_DSP_REQUEST = 2, WAIT_DSP_STOP = 3 #endif }; UWORD8 *state = &l1s.audio_state[L1S_VM_AMR_PLAY_STATE]; xSignalHeaderRec *conf_msg; UWORD8 sample_header; switch(*state) { case IDLE: { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; *state = WAIT_AUDIO_ON; #else // Initialize the buffer parameters l1s.voicememo_amr.play.ptr_buf = NULL; l1s.voicememo_amr.play.buffer_size = 0; l1s.voicememo_amr.play.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo_amr.play.ptr_buf, &l1s.voicememo_amr.play.buffer_size, l1a_l1s_com.voicememo_amr_task.play.parameters.session_id); // Convert the buffer size in bytes unit because VM AMR is defined in byte unit l1s.voicememo_amr.play.buffer_size <<= 1; // Initialize previous sample parameters in order to create ONSET on first SAMPLE l1s.voicememo_amr.play.previous_type = SC_VM_AMR_NO_DATA; l1s.voicememo_amr.play.transition_header = 0; // Initialize a_du_x // Determine which a_du buffer is currently used l1s.voicememo_amr.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo_amr.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } *(l1s.voicememo_amr.play.a_du_x) = 0; // Start the voice memo playing DSP task l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VM_VOCODER_SELECT; l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_PLAY_START; *state = WAIT_DSP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE] == L1_AUDIO_DL_ON)) { // Initialize the buffer parameters l1s.voicememo_amr.play.ptr_buf = NULL; l1s.voicememo_amr.play.buffer_size = 0; l1s.voicememo_amr.play.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo_amr.play.ptr_buf, &l1s.voicememo_amr.play.buffer_size, l1a_l1s_com.voicememo_amr_task.play.parameters.session_id); // Convert the buffer size in bytes unit because VM AMR is defined in byte unit l1s.voicememo_amr.play.buffer_size <<= 1; // Initialize previous sample parameters in order to create ONSET on first SAMPLE l1s.voicememo_amr.play.previous_type = SC_VM_AMR_NO_DATA; l1s.voicememo_amr.play.transition_header = 0; // Initialize a_du_x // Determine which a_du buffer is currently used l1s.voicememo_amr.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo_amr.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } *(l1s.voicememo_amr.play.a_du_x) = 0; // Start the voice memo playing DSP task l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VM_VOCODER_SELECT; l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_PLAY_START; *state = WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_DSP_START: { // The DSP task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_AMR_PLAY_ON_GOING) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_AMR_PLAY_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_REQUEST; } } break; case WAIT_DSP_REQUEST: { // The MMI requests to stop the voice memorization playing task if (l1a_l1s_com.voicememo_amr_task.play.command.stop) { // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_PLAY_STOP; *state = WAIT_DSP_STOP; } else // The DSP needs a new block ? { // Determine which a_du buffer is currently used l1s.voicememo_amr.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo_amr.play.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } // B_BLOCK_READY is not set if DSP is ready to get new sample if (!(*(l1s.voicememo_amr.play.a_du_x) & B_BLOCK_READY)) { // Issue: transition from not speech sample to speech sample requires creation of transition ONSET sample + storing temporarily speech header // We use it on next DSP request => when previous sample was ONSET, header must be taken from transition_header if (l1s.voicememo_amr.play.previous_type == SC_VM_AMR_ONSET) { // we use speech header temprarily stored in transition_header sample_header = l1s.voicememo_amr.play.transition_header; } else { // Download the header of the new sample l1s.voicememo_amr.play.error_id = copy_byte_data_from_buffer (l1a_l1s_com.voicememo_amr_task.play.parameters.session_id, &l1s.voicememo_amr.play.buffer_size, (UWORD8 **)&l1s.voicememo_amr.play.ptr_buf, 1, &sample_header); } // Is it the end of the voice memo data buffer? if ( sample_header == SC_VM_AMR_END_MASK ) { // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_PLAY_STOP; *state = WAIT_DSP_STOP; } else { UWORD8 temp_header; UWORD8 data_size; // Identify AMR sample RX_TX_TYPE temp_header = sample_header & SC_RX_TX_TYPE_MASK; switch(temp_header) { case SC_VM_AMR_RXTX_SPEECH_GOOD: case SC_VM_AMR_RXTX_SPEECH_BAD: { // Check if previous sample is a non speech sample so we have to create ONSET sample if ( (l1s.voicememo_amr.play.previous_type == SC_VM_AMR_NOISE)||(l1s.voicememo_amr.play.previous_type == SC_VM_AMR_NO_DATA) ) { l1s.voicememo_amr.play.previous_type = SC_VM_AMR_ONSET; l1s.voicememo_amr.play.transition_header = sample_header; sample_header = SC_VM_AMR_RXTX_ONSET; data_size = SC_VM_AMR_ONSET_DATA_SIZE; } else { l1s.voicememo_amr.play.previous_type = SC_VM_AMR_SPEECH; // read channel type to know which vocoder is used (and size of data bits) temp_header = sample_header & SC_CHAN_TYPE_MASK; switch(temp_header) { case SC_VM_AMR_SPEECH_475: data_size = SC_VM_AMR_SPEECH_475_DATA_SIZE; break; case SC_VM_AMR_SPEECH_515: data_size = SC_VM_AMR_SPEECH_515_DATA_SIZE; break; case SC_VM_AMR_SPEECH_59: data_size = SC_VM_AMR_SPEECH_59_DATA_SIZE; break; case SC_VM_AMR_SPEECH_67: data_size = SC_VM_AMR_SPEECH_67_DATA_SIZE; break; case SC_VM_AMR_SPEECH_74: data_size = SC_VM_AMR_SPEECH_74_DATA_SIZE; break; case SC_VM_AMR_SPEECH_795: data_size = SC_VM_AMR_SPEECH_795_DATA_SIZE; break; case SC_VM_AMR_SPEECH_102: data_size = SC_VM_AMR_SPEECH_102_DATA_SIZE; break; case SC_VM_AMR_SPEECH_122: data_size = SC_VM_AMR_SPEECH_122_DATA_SIZE; break; } // switch(temp_header) } } break; case SC_VM_AMR_RXTX_SID_FIRST: data_size = SC_VM_AMR_SID_FIRST_DATA_SIZE; l1s.voicememo_amr.play.previous_type = SC_VM_AMR_NOISE; break; case SC_VM_AMR_RXTX_SID_UPDATE: data_size = SC_VM_AMR_SID_UPDATE_DATA_SIZE; l1s.voicememo_amr.play.previous_type = SC_VM_AMR_NOISE; break; case SC_VM_AMR_RXTX_SID_BAD: data_size = SC_VM_AMR_SID_BAD_DATA_SIZE; l1s.voicememo_amr.play.previous_type = SC_VM_AMR_NOISE; break; case SC_VM_AMR_RXTX_NO_DATA: data_size = SC_VM_AMR_NO_DATA_DATA_SIZE; l1s.voicememo_amr.play.previous_type = SC_VM_AMR_NO_DATA; break; default: // trace error break; } // if data_size is 0 (SID_FIRST, NO_DATA and ONSET), nothing to copy if (data_size > 0) { // go beyond the 2 DSP words after the header, which are not used in MMS (so a_du_x + 3 in words) l1s.voicememo_amr.play.error_id = copy_byte_data_le_from_buffer (l1a_l1s_com.voicememo_amr_task.play.parameters.session_id, &l1s.voicememo_amr.play.buffer_size, (UWORD8 **)&l1s.voicememo_amr.play.ptr_buf, data_size, l1s.voicememo_amr.play.a_du_x + 3); } // Send the header to the DSP *l1s.voicememo_amr.play.a_du_x = (sample_header | B_BLOCK_READY); } } } } break; case WAIT_DSP_STOP: { // The DSP voice memorization playing task is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_AMR_PLAY_ON_GOING)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; #endif // L1_AUDIO_MCU_ONOFF // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_AMR_PLAY_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_vm_amr_record_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Voice memo amr recoding L1S manager task*/ /* */ /*-------------------------------------------------------*/ void l1s_vm_amr_record_manager(void) { enum states { IDLE = 0, #if (L1_AUDIO_MCU_ONOFF == 1) WAIT_AUDIO_ON = 1, WAIT_DSP_START = 2, WAIT_DSP_SAMPLE = 3, WAIT_DSP_STOP = 4 #else WAIT_DSP_START = 1, WAIT_DSP_SAMPLE = 2, WAIT_DSP_STOP = 3 #endif }; UWORD8 *state = &l1s.audio_state[L1S_VM_AMR_RECORD_STATE]; xSignalHeaderRec *conf_msg; UWORD8 sample_header; switch(*state) { case IDLE: { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request++; *state = WAIT_AUDIO_ON; #else // Initialize the buffer parameters l1s.voicememo_amr.record.ptr_buf = NULL; l1s.voicememo_amr.record.buffer_size = 0; l1s.voicememo_amr.record.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo_amr.record.ptr_buf, &l1s.voicememo_amr.record.buffer_size, l1a_l1s_com.voicememo_amr_task.record.parameters.session_id); // Convert the buffer size in bytes unit because VM AMR is defined in byte unit l1s.voicememo_amr.record.buffer_size <<= 1; // Initialize the size of the Voice memo to record l1s.voicememo_amr.record.recorded_size = 0; // Initialize the DTX mode if (l1a_l1s_com.voicememo_amr_task.record.parameters.dtx) l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VOICE_MEMO_DTX; else l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VOICE_MEMO_DTX); // Select AMR vocoder and specified channel type l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VM_VOCODER_SELECT; // AMR voice memo l1s_dsp_com.dsp_ndb_ptr->d_amms_ul_voc &= ~(SC_CHAN_TYPE_MASK); l1s_dsp_com.dsp_ndb_ptr->d_amms_ul_voc |= l1a_l1s_com.voicememo_amr_task.record.parameters.amr_vocoder; #if 0 /* FreeCalypso: not present in TCS211 object */ l1s.voicememo_amr.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo_amr.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } *(l1s.voicememo_amr.record.a_du_x) = 0; #endif // Start the voice memo recording DSP task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_RECORD_START; *state = WAIT_DSP_START; #endif // L1_AUDIO_MCU_ONOFF } break; #if (L1_AUDIO_MCU_ONOFF == 1) case WAIT_AUDIO_ON: { // Triton Audio ON/OFF Changes if((l1s.audio_state[L1S_AUDIO_UL_ONOFF_STATE] == L1_AUDIO_UL_ON)) { // Initialize the buffer parameters l1s.voicememo_amr.record.ptr_buf = NULL; l1s.voicememo_amr.record.buffer_size = 0; l1s.voicememo_amr.record.error_id = Cust_get_pointer((UWORD16 **)&l1s.voicememo_amr.record.ptr_buf, &l1s.voicememo_amr.record.buffer_size, l1a_l1s_com.voicememo_amr_task.record.parameters.session_id); // Convert the buffer size in bytes unit because VM AMR is defined in byte unit l1s.voicememo_amr.record.buffer_size <<= 1; // Initialize the size of the Voice memo to record l1s.voicememo_amr.record.recorded_size = 0; // Initialize the DTX mode if (l1a_l1s_com.voicememo_amr_task.record.parameters.dtx) l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VOICE_MEMO_DTX; else l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VOICE_MEMO_DTX); // Select AMR vocoder and specified channel type l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_VM_VOCODER_SELECT; // AMR voice memo l1s_dsp_com.dsp_ndb_ptr->d_amms_ul_voc &= ~(SC_CHAN_TYPE_MASK); l1s_dsp_com.dsp_ndb_ptr->d_amms_ul_voc |= l1a_l1s_com.voicememo_amr_task.record.parameters.amr_vocoder; l1s.voicememo_amr.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo_amr.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } *(l1s.voicememo_amr.record.a_du_x) = 0; // Start the voice memo recording DSP task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_RECORD_START; *state = WAIT_DSP_START; } } break; #endif // L1_AUDIO_MCU_ONOFF case WAIT_DSP_START: { // The DSP task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_AMR_RECORD_ON_GOING) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_AMR_RECORD_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_SAMPLE; } } // case WAIT_DSP_START: break; case WAIT_DSP_SAMPLE: { // The MMI requests to stop the voice memorization recording task if (l1a_l1s_com.voicememo_amr_task.record.command.stop) { // Write the end mask at the end of the voice data RAM buffer sample_header = SC_VM_AMR_END_MASK; l1s.voicememo_amr.record.error_id = copy_byte_data_to_buffer (l1a_l1s_com.voicememo_amr_task.record.parameters.session_id, &l1s.voicememo_amr.record.buffer_size, (UWORD8 **)&l1s.voicememo_amr.record.ptr_buf, 1, &sample_header); // Increase the recorded size l1s.voicememo_amr.record.recorded_size++; // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_RECORD_STOP; *state = WAIT_DSP_STOP; } // if (l1a_l1s_com.voicememo_amr_task.record.command.stop) else // The DSP sends a new block ? { // Determine which a_du buffer is currently used l1s.voicememo_amr.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.voicememo_amr.record.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } // The DSP sends a new block? if ( (*(l1s.voicememo_amr.record.a_du_x)) & B_BLOCK_READY ) { UWORD8 sample_header, temp_header; UWORD8 data_size; // get RX_TYPE to identify frame (SPEECH_GOOD, SID_FIRST, SID_UPDATE, NO_DATA) sample_header = (*l1s.voicememo_amr.record.a_du_x & 0x00FF); temp_header = sample_header & SC_RX_TX_TYPE_MASK; // Check if the block contains speech or SID or NO_DATA switch(temp_header) { case SC_VM_AMR_RXTX_SPEECH_GOOD: { temp_header = sample_header & SC_CHAN_TYPE_MASK; switch(temp_header) { case SC_VM_AMR_SPEECH_475: data_size = SC_VM_AMR_SPEECH_475_DATA_SIZE; break; case SC_VM_AMR_SPEECH_515: data_size = SC_VM_AMR_SPEECH_515_DATA_SIZE; break; case SC_VM_AMR_SPEECH_59: data_size = SC_VM_AMR_SPEECH_59_DATA_SIZE; break; case SC_VM_AMR_SPEECH_67: data_size = SC_VM_AMR_SPEECH_67_DATA_SIZE; break; case SC_VM_AMR_SPEECH_74: data_size = SC_VM_AMR_SPEECH_74_DATA_SIZE; break; case SC_VM_AMR_SPEECH_795: data_size = SC_VM_AMR_SPEECH_795_DATA_SIZE; break; case SC_VM_AMR_SPEECH_102: data_size = SC_VM_AMR_SPEECH_102_DATA_SIZE; break; case SC_VM_AMR_SPEECH_122: data_size = SC_VM_AMR_SPEECH_122_DATA_SIZE; break; } } // case SC_VM_AMR_RXTX_SPEECH_GOOD: break; case SC_VM_AMR_RXTX_SID_FIRST: data_size = SC_VM_AMR_SID_FIRST_DATA_SIZE; break; case SC_VM_AMR_RXTX_SID_UPDATE: data_size = SC_VM_AMR_SID_UPDATE_DATA_SIZE; break; case SC_VM_AMR_RXTX_NO_DATA: data_size = SC_VM_AMR_NO_DATA_DATA_SIZE; break; default: // trace error break; } // switch(temp_header) // The maximum allocated size is reached? (need to be able to store header + data + end_mask) if ( (l1s.voicememo_amr.record.recorded_size+data_size+SC_VM_AMR_HEADER_SIZE+SC_VM_AMR_END_MASK_SIZE) <= l1a_l1s_com.voicememo_amr_task.record.parameters.maximum_size) { // Download the header from the a_du_x buffer. l1s.voicememo_amr.record.error_id = copy_byte_data_to_buffer (l1a_l1s_com.voicememo_amr_task.record.parameters.session_id, &l1s.voicememo_amr.record.buffer_size, (UWORD8 **)&l1s.voicememo_amr.record.ptr_buf, 1, &sample_header); if (data_size > 0) { l1s.voicememo_amr.record.error_id = copy_byte_data_le_to_buffer (l1a_l1s_com.voicememo_amr_task.record.parameters.session_id, &l1s.voicememo_amr.record.buffer_size, (UWORD8 **)&l1s.voicememo_amr.record.ptr_buf, data_size, l1s.voicememo_amr.record.a_du_x + 3); } // Increase the recorded size (header + data_bits) l1s.voicememo_amr.record.recorded_size += data_size + SC_VM_AMR_HEADER_SIZE; // Clear the a_du_x header: *(l1s.voicememo_amr.record.a_du_x) = 0; } else { // Write the end mask at the end of the voice data RAM buffer sample_header = SC_VM_AMR_END_MASK; l1s.voicememo_amr.record.error_id = copy_byte_data_to_buffer (l1a_l1s_com.voicememo_amr_task.record.parameters.session_id, &l1s.voicememo_amr.record.buffer_size, (UWORD8 **)&l1s.voicememo_amr.record.ptr_buf, 1, &sample_header); // Increase the recorded size l1s.voicememo_amr.record.recorded_size++; // Clear the a_du_x header: *(l1s.voicememo_amr.record.a_du_x) = 0; // Stop the DSP voice memorization playing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_AMR_RECORD_STOP; *state = WAIT_DSP_STOP; } } } // else of if (l1a_l1s_com.voicememo_amr_task.record.command.stop) } break; case WAIT_DSP_STOP: { // The DSP voice memorization playing task is stopped if (!(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_AMR_RECORD_ON_GOING)) { // Triton Audio ON/OFF Changes #if (L1_AUDIO_MCU_ONOFF == 1) l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request--; #endif // L1_AUDIO_MCU_ONOFF // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_VM_AMR_RECORD_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_VM_AMR_RECORD_STOP_CON; //Fill the message ((T_L1_VM_AMR_RECORD_CON *)(conf_msg->SigP))->recorded_size = l1s.voicememo_amr.record.recorded_size; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch(*state) } #endif // L1_VOICE_MEMO_AMR #if (SPEECH_RECO) /*-------------------------------------------------------*/ /* l1s_sr_enroll_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : speech recognition enroll */ /* L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_sr_enroll_manager(void) { enum states { IDLE = 0, WAIT_DSP_START = 1, WAIT_ACQUISITION_STATUS = 2, WAIT_DSP_STOP = 3 }; UWORD8 *state = &l1s.audio_state[L1S_SR_ENROLL_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Initialize the status register l1s_dsp_com.dsp_ndb_ptr->d_sr_status = 0; // Disable the DSP bit exact test l1s_dsp_com.dsp_ndb_ptr->d_sr_bit_exact_test &= 0xff80; // Initialize the watchdog timer with the time to acquire a word l1s.speechreco.time_out = SC_SR_AQUISITION_TIME_OUT; // Start the DSP enroll task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_ENROLL; *state = WAIT_DSP_START; } break; case WAIT_DSP_START: { // The DSP enroll task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_SR_ENROLL_TASK) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_ENROLL_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_ACQUISITION_STATUS; } } break; case WAIT_ACQUISITION_STATUS: { // the allowed time isn't out if (l1s.speechreco.time_out--) { // The DSP enroll task ran bad or the MMI stop the enroll task if ( (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_BAD_ACQUISITION) || (l1a_l1s_com.speechreco_task.command.enroll_stop) ) { // Error: bad acquisition l1s.speechreco.error = SC_BAD_ACQUISITION; // Stop the DSP enroll task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } else // The DSP enroll task ran good if (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_GOOD_ACQUISITION) { // No error l1s.speechreco.error = SC_NO_ERROR; // Stop the DSP enroll task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } else { // Error: time is out l1s.speechreco.error = SC_TIME_OUT; // Stop the DSP enroll task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } break; case WAIT_DSP_STOP: { // The DSP enroll task is stopped if ( !(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & (B_SR_ENROLL_TASK | B_VM_RECORD_ON_GOING)) ) { // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_SR_ENROLL_STOP_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_ENROLL_STOP_CON; //Fill the message ((T_L1_SR_ENROLL_STOP_CON *)(conf_msg->SigP))->error_id = l1s.speechreco.error; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_sr_update_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : speech recognition update */ /* L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_sr_update_manager(void) { enum states { IDLE = 0, WAIT_DSP_START = 1, WAIT_ACQUISITION_STATUS = 2, WAIT_UPDATE_STATUS = 3, WAIT_DSP_STOP = 4 }; UWORD8 *state = &l1s.audio_state[L1S_SR_UPDATE_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Initialize the status register l1s_dsp_com.dsp_ndb_ptr->d_sr_status = 0; // Disable the DSP bit exact test l1s_dsp_com.dsp_ndb_ptr->d_sr_bit_exact_test &= 0xff80; // Initialize the watchdog timer with the time to acquire a word l1s.speechreco.time_out = SC_SR_AQUISITION_TIME_OUT; // Start the DSP update task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_UPDATE; #if (W_A_DSP_SR_BGD) // Management of DSP tasks in background if (l1s_dsp_com.dsp_param_ptr->d_gsm_bgd_mgt & B_DSPBGD_UPD) { l1s_dsp_com.dsp_ndb_ptr->d_background_enable |= (1 << C_BGD_ALIGN); } #endif *state = WAIT_DSP_START; } break; case WAIT_DSP_START: { // The DSP update task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_SR_UPDATE_TASK) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_UPDATE_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_ACQUISITION_STATUS; } } break; case WAIT_ACQUISITION_STATUS: { // the allowed time isn't out if (l1s.speechreco.time_out--) { // The DSP acquisition task ran bad or the MMI stop the update task if ( (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_BAD_ACQUISITION) || (l1a_l1s_com.speechreco_task.command.update_stop) ) { // Error: bad acquisition l1s.speechreco.error = SC_BAD_ACQUISITION; // Stop the DSP acquisition task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } else // The DSP enroll task ran good if (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_GOOD_ACQUISITION) { // Initialize the watchdog timer with the time to update a word l1s.speechreco.time_out = SC_SR_UPDATE_TIME_OUT; *state = WAIT_UPDATE_STATUS; } } else { // Error: time is out l1s.speechreco.error = SC_TIME_OUT; // Stop the DSP acquisition task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } break; case WAIT_UPDATE_STATUS: { // the allowed time isn't out if (l1s.speechreco.time_out--) { // The DSP update task ran bad or the MMI stop the update task if ( (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_BAD_UPDATE) || (l1a_l1s_com.speechreco_task.command.update_stop) ) { // Error: bad update l1s.speechreco.error = SC_BAD_UPDATE; // Stop the DSP update task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } else // The DSP update task ran good if (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_GOOD_UPDATE) { // No error: l1s.speechreco.error = SC_NO_ERROR; // Stop the DSP update task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } else { // Error: time is out l1s.speechreco.error = SC_TIME_OUT; // Stop the DSP enroll task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } break; case WAIT_DSP_STOP: { // The DSP enroll task is stopped if ( !( l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & (B_SR_UPDATE_TASK | B_SR_ALIGNMENT_TASK | B_VM_RECORD_ON_GOING) ) ) { #if (W_A_DSP_SR_BGD) // Management of DSP tasks in background if (l1s_dsp_com.dsp_param_ptr->d_gsm_bgd_mgt & B_DSPBGD_UPD) { l1s_dsp_com.dsp_ndb_ptr->d_background_enable &= ~(1 << C_BGD_ALIGN); } #endif // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_SR_UPDATE_STOP_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_UPDATE_STOP_CON; //Fill the message ((T_L1_SR_UPDATE_STOP_CON *)(conf_msg->SigP))->error_id = l1s.speechreco.error; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_sr_reco_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : speech recognition reco acquisition */ /* L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_sr_reco_manager(void) { enum states { IDLE = 0, WAIT_DSP_START = 1, WAIT_ACQUISITION_STATUS = 2, WAIT_DSP_STOP = 3 }; UWORD8 *state = &l1s.audio_state[L1S_SR_RECO_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Initialize the status register l1s_dsp_com.dsp_ndb_ptr->d_sr_status = 0; // Disable the DSP bit exact test l1s_dsp_com.dsp_ndb_ptr->d_sr_bit_exact_test &= 0xff80; // Initialize the watchdog timer with the time to acquire a word l1s.speechreco.time_out = SC_SR_AQUISITION_TIME_OUT; // Start the DSP acquisition reco task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_RECO; *state = WAIT_DSP_START; } break; case WAIT_DSP_START: { // The DSP reco task is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_SR_RECO_TASK) { // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_RECO_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_ACQUISITION_STATUS; } } break; case WAIT_ACQUISITION_STATUS: { // the allowed time isn't out if (l1s.speechreco.time_out--) { // The DSP acquisition reco task ran bad or the MMI stop the acquisition reco task if ( (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_BAD_ACQUISITION) || (l1a_l1s_com.speechreco_task.command.reco_stop) ) { // Error: bad acquisition l1s.speechreco.error = SC_BAD_ACQUISITION; // Stop the DSP acquisition reco task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } else // The DSP enroll task ran good if (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_GOOD_ACQUISITION) { // No error l1s.speechreco.error = SC_NO_ERROR; // Stop the DSP acquisition reco task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } else { // Error: time is out l1s.speechreco.error = SC_TIME_OUT; // Stop the DSP acquisition reco task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } break; case WAIT_DSP_STOP: { // The DSP enroll task is stopped if ( !(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_SR_RECO_TASK) ) { // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_SR_RECO_STOP_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_RECO_STOP_CON; //Fill the message ((T_L1_SR_RECO_STOP_CON *)(conf_msg->SigP))->error_id = l1s.speechreco.error; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_sr_processing_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : speech recognition reco processing */ /* L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_sr_processing_manager(void) { enum states { IDLE = 0, WAIT_DSP_PROCESSING_STOP = 1, WAIT_DSP_RESULT = 2, WAIT_DSP_STOP = 3 }; UWORD8 *state = &l1s.audio_state[L1S_SR_PROCESSING_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Initialize the status register l1s_dsp_com.dsp_ndb_ptr->d_sr_status = 0; // Disable the DSP bit exact test l1s_dsp_com.dsp_ndb_ptr->d_sr_bit_exact_test &= 0xff80; // Initialize the OOV algorithm l1s_dsp_com.dsp_ndb_ptr->d_sr_param &= 0x20; l1s_dsp_com.dsp_ndb_ptr->d_sr_param |= SC_SR_OOV_SFT_THR; // Transmit ot the DSP the number of word to compare l1s_dsp_com.dsp_ndb_ptr->d_sr_nb_words = l1a_l1s_com.speechreco_task.parameters.vocabulary_size; // Initialize the watchdog timer with the time to process a word l1s.speechreco.time_out = SC_SR_PROCESSING_TIME_OUT; // Start the DSP processing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_PROCESSING; #if (W_A_DSP_SR_BGD) // Management of DSP tasks in background if (l1s_dsp_com.dsp_param_ptr->d_gsm_bgd_mgt & B_DSPBGD_RECO) { l1s_dsp_com.dsp_ndb_ptr->d_background_enable |= (1 << C_BGD_RECOGN); } #endif // Reset the start command l1a_l1s_com.speechreco_task.command.processing_start = FALSE; *state = WAIT_DSP_PROCESSING_STOP; } break; case WAIT_DSP_PROCESSING_STOP: { if (l1s.speechreco.time_out--) { // The MMI stops the processing task if (l1a_l1s_com.speechreco_task.command.processing_stop) { // Error: bad acquisition l1s.speechreco.error = SC_BAD_RECOGNITION; // Stop the DSP processing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } else // The DSP processing task is stopped if ( !(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_SR_PROCESSING_TASK) ) { // It was the last model if (l1a_l1s_com.speechreco_task.parameters.index_counter == l1a_l1s_com.speechreco_task.parameters.vocabulary_size) { *state = WAIT_DSP_RESULT; } else { // Send the stop confirmation message with no error // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_SR_PROCESSING_STOP_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_PROCESSING_STOP_CON; //Fill the message ((T_L1_SR_PROCESSING_STOP_CON *)(conf_msg->SigP))->error_id = SC_NO_ERROR; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } } else // the allowed time is out { // Error: time is out l1s.speechreco.error = SC_TIME_OUT; // Stop the DSP processing task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_SR_STOP; *state = WAIT_DSP_STOP; } } break; case WAIT_DSP_RESULT: { #if (W_A_DSP_SR_BGD) // Management of DSP tasks in background if (l1s_dsp_com.dsp_param_ptr->d_gsm_bgd_mgt & B_DSPBGD_RECO) { l1s_dsp_com.dsp_ndb_ptr->d_background_enable &= ~(1 << C_BGD_RECOGN); } #endif // The DSP recognition task was bad if (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_BAD_ACQUISITION) { // Send the stop indication message with an bad recognition error // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_SR_RECO_STOP_IND)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_RECO_STOP_IND; //Fill the message ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->error_id = SC_BAD_RECOGNITION; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } else // The DSP recognition task was good: { // Send the stop indication message without any error // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_SR_RECO_STOP_IND)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_RECO_STOP_IND; //Fill the message ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->error_id = SC_NO_ERROR; ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->best_word_index = l1s_dsp_com.dsp_ndb_ptr->a_n_best_words[0]; ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->best_word_score = l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[0] | (l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[1] << 16); ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->second_best_word_index = l1s_dsp_com.dsp_ndb_ptr->a_n_best_words[1]; ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->second_best_word_score = l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[2] | (l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[3] << 16); ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->third_best_word_index = l1s_dsp_com.dsp_ndb_ptr->a_n_best_words[2]; ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->third_best_word_score = l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[4] | (l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[5] << 16); ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->fourth_best_word_index = l1s_dsp_com.dsp_ndb_ptr->a_n_best_words[3]; ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->fourth_best_word_score = l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[6] | (l1s_dsp_com.dsp_ndb_ptr->a_n_best_score[7] << 16); ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->d_sr_db_level = l1s_dsp_com.dsp_ndb_ptr->d_sr_db_level; ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->d_sr_db_noise = l1s_dsp_com.dsp_ndb_ptr->d_sr_db_noise; ((T_L1_SR_RECO_STOP_IND *)(conf_msg->SigP))->d_sr_model_size = l1s_dsp_com.dsp_ndb_ptr->d_sr_mod_size; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; case WAIT_DSP_STOP: { // The DSP processing task is stopped if ( !(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_SR_PROCESSING_TASK) ) { // Send the stop confirmation message with an error // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_SR_PROCESSING_STOP_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_SR_PROCESSING_STOP_CON; //Fill the message ((T_L1_SR_PROCESSING_STOP_CON *)(conf_msg->SigP))->error_id = l1s.speechreco.error; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } /*-------------------------------------------------------*/ /* l1s_sr_speech_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : speech recognition speech recording */ /* L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_sr_speech_manager(void) { enum states { IDLE = 0, WAIT_DSP_START = 1, WAIT_DSP_SAMPLE = 2, WAIT_DSP_STOP = 3 }; UWORD8 *state = &l1s.audio_state[L1S_SR_SPEECH_STATE]; API *a_du_x; UWORD8 i; switch(*state) { case IDLE: { // Initialize the current pointer l1s.speechreco.speech_pointer = l1a_l1s_com.speechreco_task.parameters.speech_address; l1s.speechreco.end_pointer = (UWORD16 *)(l1s.speechreco.speech_pointer + SC_SR_MMI_2_L1_SPEECH_SIZE); // Initialize the flag to know if it's the first pass in the circular buffer l1s.speechreco.first_pass = TRUE; // Initialize the status register l1s_dsp_com.dsp_ndb_ptr->d_sr_status = 0; // No DTX mode l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VOICE_MEMO_DTX); #if ((DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)) // use TCH/FS vocoder l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~(B_VM_VOCODER_SELECT); #endif // Start the voice memo recodgin DSP task: l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_RECORD_START; *state = WAIT_DSP_START; } break; case WAIT_DSP_START: { // The DSP is started if (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_RECORD_ON_GOING) { *state = WAIT_DSP_SAMPLE; } } break; case WAIT_DSP_SAMPLE: { // A beginning of word is detected if ( ((l1s_dsp_com.dsp_ndb_ptr->d_sr_status & SC_SR_WORD_MASK) == SC_SR_WORD_BEGINNING) && (l1s.speechreco.speech_old_status == SC_SR_WORD_SEARCHING) ) { // Calculate the address of the beginning of the word l1a_l1s_com.speechreco_task.parameters.start_address = l1s.speechreco.speech_pointer - ((SC_SR_SPEECH_WORD_BEGIN_VAD_LATENCY + SC_SR_SPEECH_WORD_BEGIN_MARGIN) * SC_SR_SPEECH_FRAME_SIZE); if (l1a_l1s_com.speechreco_task.parameters.start_address < l1a_l1s_com.speechreco_task.parameters.speech_address) { if (l1s.speechreco.first_pass == FALSE) { l1a_l1s_com.speechreco_task.parameters.start_address = l1s.speechreco.end_pointer - ( l1a_l1s_com.speechreco_task.parameters.speech_address - (l1s.speechreco.speech_pointer - ((SC_SR_SPEECH_WORD_BEGIN_VAD_LATENCY + SC_SR_SPEECH_WORD_BEGIN_MARGIN) * SC_SR_SPEECH_FRAME_SIZE)) ); } else { l1a_l1s_com.speechreco_task.parameters.start_address = l1a_l1s_com.speechreco_task.parameters.speech_address; } } } else // A end of word is detected if ( ((l1s_dsp_com.dsp_ndb_ptr->d_sr_status & SC_SR_WORD_MASK) == SC_SR_WORD_ENDING) && (l1s.speechreco.speech_old_status == SC_SR_WORD_ON_GOING) ) { // Calculate the address of the end of the word l1a_l1s_com.speechreco_task.parameters.stop_address = l1s.speechreco.speech_pointer - ((SC_SR_SPEECH_WORD_END_VAD_LATENCY - SC_SR_SPEECH_WORD_END_MARGIN)* SC_SR_SPEECH_FRAME_SIZE); if (l1a_l1s_com.speechreco_task.parameters.stop_address < l1a_l1s_com.speechreco_task.parameters.speech_address) { l1a_l1s_com.speechreco_task.parameters.stop_address = l1s.speechreco.end_pointer - ( l1a_l1s_com.speechreco_task.parameters.speech_address - (l1s.speechreco.speech_pointer - ((SC_SR_SPEECH_WORD_END_VAD_LATENCY - SC_SR_SPEECH_WORD_END_MARGIN) * SC_SR_SPEECH_FRAME_SIZE)) ); } } // Save the current status l1s.speechreco.speech_old_status = l1s_dsp_com.dsp_ndb_ptr->d_sr_status & SC_SR_WORD_MASK; // Determine which a_du buffer is currently used l1s.speechreco.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_1; if (l1a_l1s_com.dedic_set.aset != NULL) { if ( (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type == TCH_H) && (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel == 1) ) l1s.speechreco.a_du_x = l1s_dsp_com.dsp_ndb_ptr->a_du_0; } // The acquisition was good if (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_GOOD_ACQUISITION) { // Stop the voice memorization recording task l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_RECORD_STOP; *state = WAIT_DSP_STOP; } else // The task must be stopped if ( (l1s_dsp_com.dsp_ndb_ptr->d_sr_status & B_BAD_ACQUISITION) || (l1a_l1s_com.speechreco_task.command.speech_stop) || (l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init & B_SR_STOP) ) { // Stop the DSP voice memorization recording task: l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= B_VM_RECORD_STOP; *state = WAIT_DSP_STOP; } else // The DSP sends a new block if (l1s.speechreco.a_du_x[0] & B_BLOCK_READY) { // Is there enough place in the RAM buffer if (l1s.speechreco.speech_pointer == l1s.speechreco.end_pointer) { // Rewind the current pointer l1s.speechreco.speech_pointer = l1a_l1s_com.speechreco_task.parameters.speech_address; // It isn't the first pass l1s.speechreco.first_pass = FALSE; } // Download the speech sample from the a_du_x to the RAM buffer a_du_x = l1s.speechreco.a_du_x; for(i=0; i < SC_SR_SPEECH_FRAME_SIZE; i++) { *(l1s.speechreco.speech_pointer)++ = *a_du_x++; } // Clear the a_du_x header l1s.speechreco.a_du_x[0] = 0; } } break; case WAIT_DSP_STOP: { // The DSP speech recoding task is stopped if ( !(l1s_dsp_com.dsp_ndb_ptr->d_toneskb_status & B_VM_RECORD_ON_GOING) ) { *state = IDLE; } } break; } // switch } #endif // SPEECH_RECO #if (AEC == 1) /*-------------------------------------------------------*/ /* l1s_aec_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : AEC L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_aec_manager(void) { enum states { IDLE = 0, #if (L1_NEW_AEC) WAIT_DSP_AVAILABLE = 1, AEC_VISIBILITY = 2 #else WAIT_DSP_AVAILABLE = 1 #endif }; UWORD8 *state = &l1s.audio_state[L1S_AEC_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Set the d_aec_ctrl register l1s.aec.aec_control = (l1a_l1s_com.aec_task.parameters.aec_control | B_AEC_ACK); #if (L1_NEW_AEC) l1s.aec.aec_visibility = (l1s.aec.aec_control & B_AEC_VISIBILITY) >> SC_AEC_VISIBILITY_SHIFT; l1s.aec.cont_filter = l1a_l1s_com.aec_task.parameters.cont_filter; l1s.aec.granularity_att = l1a_l1s_com.aec_task.parameters.granularity_att; l1s.aec.coef_smooth = l1a_l1s_com.aec_task.parameters.coef_smooth; l1s.aec.es_level_max = l1a_l1s_com.aec_task.parameters.es_level_max; l1s.aec.fact_vad = l1a_l1s_com.aec_task.parameters.fact_vad; l1s.aec.thrs_abs = l1a_l1s_com.aec_task.parameters.thrs_abs; l1s.aec.fact_asd_fil = l1a_l1s_com.aec_task.parameters.fact_asd_fil; l1s.aec.fact_asd_mut = l1a_l1s_com.aec_task.parameters.fact_asd_mut; #endif // Reset the start command l1a_l1s_com.aec_task.command.start = FALSE; // Send the AEC confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AEC_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_AVAILABLE; } break; case WAIT_DSP_AVAILABLE: { // the new settings come from the MMI if (l1a_l1s_com.aec_task.command.start) { // Set the d_aec_ctrl register l1s.aec.aec_control = (l1a_l1s_com.aec_task.parameters.aec_control | B_AEC_ACK); #if (L1_NEW_AEC) l1s.aec.aec_visibility = (l1s.aec.aec_control & B_AEC_VISIBILITY) >> SC_AEC_VISIBILITY_SHIFT; l1s.aec.cont_filter = l1a_l1s_com.aec_task.parameters.cont_filter; l1s.aec.granularity_att = l1a_l1s_com.aec_task.parameters.granularity_att; l1s.aec.coef_smooth = l1a_l1s_com.aec_task.parameters.coef_smooth; l1s.aec.es_level_max = l1a_l1s_com.aec_task.parameters.es_level_max; l1s.aec.fact_vad = l1a_l1s_com.aec_task.parameters.fact_vad; l1s.aec.thrs_abs = l1a_l1s_com.aec_task.parameters.thrs_abs; l1s.aec.fact_asd_fil = l1a_l1s_com.aec_task.parameters.fact_asd_fil; l1s.aec.fact_asd_mut = l1a_l1s_com.aec_task.parameters.fact_asd_mut; #endif // Reset the start command l1a_l1s_com.aec_task.command.start = FALSE; // Send the AEC confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AEC_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } // the new settings can be written to the DSP #if(DSP == 38) || (DSP == 39) if ( (l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl & B_AEC_ACK) == FALSE ) #else if ( (l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl & B_AEC_ACK) == FALSE ) #endif { #if(DSP == 38) || (DSP == 39) l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl = l1s.aec.aec_control; #else l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl = l1s.aec.aec_control; #endif #if (L1_NEW_AEC) l1s_dsp_com.dsp_ndb_ptr->d_cont_filter = l1s.aec.cont_filter; l1s_dsp_com.dsp_ndb_ptr->d_granularity_att = l1s.aec.granularity_att; l1s_dsp_com.dsp_ndb_ptr->d_coef_smooth = l1s.aec.coef_smooth; l1s_dsp_com.dsp_ndb_ptr->d_es_level_max = l1s.aec.es_level_max; l1s_dsp_com.dsp_ndb_ptr->d_fact_vad = l1s.aec.fact_vad; l1s_dsp_com.dsp_ndb_ptr->d_thrs_abs = l1s.aec.thrs_abs; l1s_dsp_com.dsp_ndb_ptr->d_fact_asd_fil = l1s.aec.fact_asd_fil; l1s_dsp_com.dsp_ndb_ptr->d_fact_asd_mut = l1s.aec.fact_asd_mut; // AEC visibility allows tracing some AEC internal output values if (l1s.aec.aec_visibility) *state = AEC_VISIBILITY; else *state = IDLE; #else *state = IDLE; #endif } } break; #if (L1_NEW_AEC) case AEC_VISIBILITY: { // the new settings come from the MMI if (l1a_l1s_com.aec_task.command.start) { // Set the d_aec_ctrl register l1s.aec.aec_control = (l1a_l1s_com.aec_task.parameters.aec_control | B_AEC_ACK); l1s.aec.aec_visibility = (l1s.aec.aec_control & B_AEC_VISIBILITY) >> SC_AEC_VISIBILITY_SHIFT; l1s.aec.cont_filter = l1a_l1s_com.aec_task.parameters.cont_filter; l1s.aec.granularity_att = l1a_l1s_com.aec_task.parameters.granularity_att; l1s.aec.coef_smooth = l1a_l1s_com.aec_task.parameters.coef_smooth; l1s.aec.es_level_max = l1a_l1s_com.aec_task.parameters.es_level_max; l1s.aec.fact_vad = l1a_l1s_com.aec_task.parameters.fact_vad; l1s.aec.thrs_abs = l1a_l1s_com.aec_task.parameters.thrs_abs; l1s.aec.fact_asd_fil = l1a_l1s_com.aec_task.parameters.fact_asd_fil; l1s.aec.fact_asd_mut = l1a_l1s_com.aec_task.parameters.fact_asd_mut; // Reset the start command l1a_l1s_com.aec_task.command.start = FALSE; // Send the AEC confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AEC_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_DSP_AVAILABLE; } if ( (l1a_l1s_com.dedic_set.aset != NULL) && ((l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_FS_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_HS_MODE) || (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_EFR_MODE)) ) { l1s.aec.visibility_interval--; if (l1s.aec.visibility_interval < 0) { conf_msg = os_alloc_sig(sizeof(T_L1_AEC_IND)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AEC_IND; ((T_L1_AEC_IND *)(conf_msg->SigP))->es_level = l1s_dsp_com.dsp_ndb_ptr->d_es_level_api; ((T_L1_AEC_IND *)(conf_msg->SigP))->far_end_pow = ( (l1s_dsp_com.dsp_ndb_ptr->d_far_end_pow_h << 16) | (l1s_dsp_com.dsp_ndb_ptr->d_far_end_pow_l)); ((T_L1_AEC_IND *)(conf_msg->SigP))->far_end_noise = ( (l1s_dsp_com.dsp_ndb_ptr->d_far_end_noise_h << 16) | (l1s_dsp_com.dsp_ndb_ptr->d_far_end_noise_l)); // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) // reset delay between 2 traces l1s.aec.visibility_interval = SC_AEC_VISIBILITY_INTERVAL; } } else // It forces aec traces when entering dedicated mode l1s.aec.visibility_interval = 1; } break; #endif } // switch } #endif // AEC #if(AEC == 2) /*-------------------------------------------------------*/ /* l1s_aec_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : AEC L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_aec_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_AEC_STATE]; xSignalHeaderRec *conf_msg; UWORD16 current_state; static T_AEC_ACTION l1s_aec_action = L1_AQI_AEC_STOPPED; static UWORD16 l_aec_ctrl; switch(*state) { case IDLE: { current_state = l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & 0x0800; if((l1a_l1s_com.aec_task.aec_control == L1_AQI_AEC_START)||(l1a_l1s_com.aec_task.aec_control == L1_AQI_AEC_UPDATE)) { if(current_state ) { #if(DSP == 38) || (DSP == 39) l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl = l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl | 0x0004; #else l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl = l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl | 0x0004; #endif l_aec_ctrl = 0x0004; l1s_aec_action = L1_AQI_AEC_UPDATED; } else { #if(DSP == 38) || (DSP == 39) l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl = l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl | 0x0001; #else l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl = l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl | 0x0001; #endif l_aec_ctrl = 0x0001; l1s_aec_action = L1_AQI_AEC_STARTED; } l1s_dsp_com.dsp_ndb_ptr->d_cont_filter = l1a_l1s_com.aec_task.parameters.cont_filter; l1s_dsp_com.dsp_ndb_ptr->d_granularity_att = l1a_l1s_com.aec_task.parameters.granularity_att; l1s_dsp_com.dsp_ndb_ptr->d_coef_smooth = l1a_l1s_com.aec_task.parameters.coef_smooth; l1s_dsp_com.dsp_ndb_ptr->d_es_level_max = l1a_l1s_com.aec_task.parameters.es_level_max; l1s_dsp_com.dsp_ndb_ptr->d_fact_vad = l1a_l1s_com.aec_task.parameters.fact_vad; l1s_dsp_com.dsp_ndb_ptr->d_thrs_abs = l1a_l1s_com.aec_task.parameters.thrs_abs; l1s_dsp_com.dsp_ndb_ptr->d_fact_asd_fil = l1a_l1s_com.aec_task.parameters.fact_asd_fil; l1s_dsp_com.dsp_ndb_ptr->d_fact_asd_mut = l1a_l1s_com.aec_task.parameters.fact_asd_mut; l1s_dsp_com.dsp_ndb_ptr->d_aec_mode = l1a_l1s_com.aec_task.parameters.aec_mode; l1s_dsp_com.dsp_ndb_ptr->d_mu = l1a_l1s_com.aec_task.parameters.mu; l1s_dsp_com.dsp_ndb_ptr->d_scale_input_ul = l1a_l1s_com.aec_task.parameters.scale_input_ul; l1s_dsp_com.dsp_ndb_ptr->d_scale_input_dl = l1a_l1s_com.aec_task.parameters.scale_input_dl; l1s_dsp_com.dsp_ndb_ptr->d_div_dmax = l1a_l1s_com.aec_task.parameters.div_dmax; l1s_dsp_com.dsp_ndb_ptr->d_div_swap_good = l1a_l1s_com.aec_task.parameters.div_swap_good; l1s_dsp_com.dsp_ndb_ptr->d_div_swap_bad = l1a_l1s_com.aec_task.parameters.div_swap_bad; l1s_dsp_com.dsp_ndb_ptr->d_block_init = l1a_l1s_com.aec_task.parameters.block_init; } else if(l1a_l1s_com.aec_task.aec_control == L1_AQI_AEC_STOP) { if(current_state ) { #if(DSP == 38) || (DSP == 39) l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl = (l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl) | 0x0002; #else l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl = (l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl) | 0x0002; #endif l_aec_ctrl = 0x0002; l1s_aec_action = L1_AQI_AEC_STOPPED; } else { l1a_l1s_com.aec_task.command.start = FALSE; // Send the AEC confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_AQI_AEC_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_AEC_CON; ((T_L1_AQI_AEC_CON*)(conf_msg->SigP))->aec_action = L1_AQI_AEC_NO_ACTION; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) return; } } *state = WAIT_DSP_ACK; break; } case WAIT_DSP_ACK: { #if(DSP == 38) || (DSP == 39) if(((l1s_dsp_com.dsp_ndb_ptr->d_aec_ul_ctrl) & (l_aec_ctrl)) == 0) #else if(((l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl) & (l_aec_ctrl)) == 0) #endif { l1a_l1s_com.aec_task.command.start = FALSE; // Send the AEC confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_AQI_AEC_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_AEC_CON; ((T_L1_AQI_AEC_CON*)(conf_msg->SigP))->aec_action = l1s_aec_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } break; } }/* End of switch statement */ } #endif #if (FIR) /*-------------------------------------------------------*/ /* l1s_fir_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : FIR L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_fir_manager(void) { xSignalHeaderRec *conf_msg; UWORD8 i; // Update the DL FIR? if (l1a_l1s_com.fir_task.parameters.update_fir & DL_FIR) { // Download the DL FIR coefficients to the melody a_fir31_downlink for (i=0; i<MAX_FIR_COEF; i++) { #if (DSP >= 33) // For this DSP code the FIR coefficients are in API param memory l1s_dsp_com.dsp_param_ptr->a_fir31_downlink[i] = *l1a_l1s_com.fir_task.parameters.fir_dl_coefficient++; #else l1s_dsp_com.dsp_ndb_ptr->a_fir31_downlink[i] = *l1a_l1s_com.fir_task.parameters.fir_dl_coefficient++; #endif } } // Update the UL FIR? if (l1a_l1s_com.fir_task.parameters.update_fir & UL_FIR) { // Download the UL FIR coefficients to the melody a_fir31_uplink for (i=0; i<MAX_FIR_COEF; i++) { #if (DSP >= 33) // For this DSP code the FIR coefficients are in API param memory l1s_dsp_com.dsp_param_ptr->a_fir31_uplink[i] = *l1a_l1s_com.fir_task.parameters.fir_ul_coefficient++; #else l1s_dsp_com.dsp_ndb_ptr->a_fir31_uplink[i] = *l1a_l1s_com.fir_task.parameters.fir_ul_coefficient++; #endif } } // Set the FIR loop back: if (l1a_l1s_com.fir_task.parameters.fir_loop) { #if (DSP == 17) || (DSP == 32) l1s_dsp_com.dsp_ndb_ptr->d_audio_init &= ~(B_FIR_START); #endif l1s_dsp_com.dsp_ndb_ptr->d_audio_init |= B_FIR_LOOP; } else { #if (DSP == 17) || (DSP == 32) l1s_dsp_com.dsp_ndb_ptr->d_audio_init |= B_FIR_START; #endif l1s_dsp_com.dsp_ndb_ptr->d_audio_init &= ~(B_FIR_LOOP); } // Send the FIR confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AUDIO_FIR_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) // Reset the start command l1a_l1s_com.fir_task.command.start = FALSE; } #endif // FIR #if (AUDIO_MODE) /*-------------------------------------------------------*/ /* l1s_audio_mode_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Audio mode L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_audio_mode_manager(void) { enum states { IDLE = 0, WAIT_DSP_CONFIRM = 1 }; UWORD8 *state = &l1s.audio_state[L1S_AUDIO_MODE_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Reset the d_audio_init l1s_dsp_com.dsp_ndb_ptr->d_audio_init &= ~(B_GSM_ONLY | B_BT_HEADSET | B_BT_CORDLESS); // Set the new mode l1s_dsp_com.dsp_ndb_ptr->d_audio_init |= l1a_l1s_com.audio_mode_task.parameters.audio_mode; *state = WAIT_DSP_CONFIRM; } break; case WAIT_DSP_CONFIRM: { // the DSP acknowledges the new settings. if ( l1s_dsp_com.dsp_ndb_ptr->d_audio_init == l1s_dsp_com.dsp_ndb_ptr->d_audio_status ) { // Send the Audio mode confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AUDIO_MODE_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) // Reset the start command l1a_l1s_com.audio_mode_task.command.start = FALSE; *state = IDLE; } } break; } // switch } #endif // AUDIO_MODE #if (MELODY_E2) /*-------------------------------------------------------*/ /* l1s_melody0_e2_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Audio melody 0 format E2 L1S manager */ /* task. */ /* */ /*-------------------------------------------------------*/ void l1s_melody0_e2_manager(void) { enum states { M0_INACTIVE = 0, M0_ALIGN_40MS_BOUNDARY = 1, M0_WAIT_COUNTER_EQUAL_0 = 2, M0_WAIT_END_MELODY = 3 }; UWORD8 *state = &l1s.audio_state[L1S_MELODY0_E2_STATE]; xSignalHeaderRec *conf_msg; UWORD8 trash[SC_MELODY_E2_MAXIMUM_HEADER_SIZE+1], oscillator_number, extension_index; UWORD16 oscillator_not_available; switch(*state) { case M0_INACTIVE: { // Reset the commands: l1a_l1s_com.melody0_e2_task.command.start = FALSE; // Initialize the pointer and size to the new description l1s.melody0_e2.ptr_buf = l1a_l1s_com.melody0_e2_task.parameters.ptr_buf; l1s.melody0_e2.buffer_size = l1a_l1s_com.melody0_e2_task.parameters.buffer_size; *state = M0_ALIGN_40MS_BOUNDARY; } break; case M0_ALIGN_40MS_BOUNDARY: { // Initialize the counter to the first time l1s.melody0_e2.error_id = copy_byte_data_from_buffer (l1a_l1s_com.melody0_e2_task.parameters.session_id, &l1s.melody0_e2.buffer_size, (UWORD8 **)&l1s.melody0_e2.ptr_buf, 1, (UWORD8 *)(&l1s.melody0_e2.counter)); // Save the extension flag l1s.melody0_e2.extension_flag = Field(l1s.melody0_e2.counter, SC_MELODY_E2_EXTENSION_FLAG_MASK, SC_MELODY_E2_EXTENSION_FLAG_SHIFT); // Save delta-time in 20ms unit l1s.melody0_e2.counter = Field(l1s.melody0_e2.counter, SC_MELODY_E2_DELTA_TIME_MASK, SC_MELODY_E2_DELTA_TIME_SHIFT); l1s.melody0_e2.note_start_20ms = l1s.melody0_e2.counter; // Adjust note_start on 20ms boundary because global counter could be running for another melody or loopback // Timebase can be computed as k*60ms + timebase_mod_60ms l1s.melody0_e2.note_start_20ms += ((l1s.melody_e2.timebase - l1s.melody_e2.timebase_mod_60ms) / 13 * 3); if (l1s.melody_e2.timebase_mod_60ms < 4) { l1s.melody0_e2.note_start_20ms += 1; } else if (l1s.melody_e2.timebase_mod_60ms < 8) { l1s.melody0_e2.note_start_20ms += 2; } else if (l1s.melody_e2.timebase_mod_60ms < 13) { l1s.melody0_e2.note_start_20ms += 3; } // Align on 40ms boundary if ( (l1s.melody0_e2.note_start_20ms & 1) == 1 ) l1s.melody0_e2.note_start_20ms++; // Convert to TDMA l1s.melody0_e2.counter = audio_twentyms_to_TDMA_convertion(l1s.melody0_e2.note_start_20ms); // Compute TDMA to wait (-1 to take into account this TDMA) l1s.melody0_e2.counter = l1s.melody0_e2.counter - l1s.melody_e2.timebase - 1; // Wait to download the first description *state = M0_WAIT_COUNTER_EQUAL_0; } // M0_INIT break; case M0_WAIT_COUNTER_EQUAL_0: { // Stop command if (l1a_l1s_com.melody0_e2_task.command.stop) { // wait until all the ocillator are stopped *state = M0_WAIT_END_MELODY; } else if (l1s.melody0_e2.counter > 0) { // Decrease the counter l1s.melody0_e2.counter--; } else { // Wait until the semaphore is set to 0 by the DSP if (!(l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_semaphore & SC_MELODY_E2_SEMAPHORE_MASK)) { // Initialize oscillators available, oscillators can be used by the DSP (d_melody_e2_osc_active) // or by the other melody E2 generator (melody_e2_osc_stop) oscillator_not_available = l1s.melody_e2.global_osc_active | l1s.melody_e2.global_osc_to_start; // find an available oscillator oscillator_number = 0; while( (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) && (oscillator_not_available & (0x0001<<oscillator_number)) ) { oscillator_number++; } // Initialize end of file l1s.melody0_e2.end_of_file = FALSE; // download the description until the delta time is different from 0 // or end of the melody file while ( (l1s.melody0_e2.counter == 0) && (l1s.melody0_e2.end_of_file == FALSE) ) { // Download the byte of the note descriptor extension in trash l1s.melody0_e2.error_id= copy_byte_data_from_buffer (l1a_l1s_com.melody0_e2_task.parameters.session_id, &l1s.melody0_e2.buffer_size, (UWORD8 **)&l1s.melody0_e2.ptr_buf, 2, &trash[0]); // Check end of melody if ( (trash[0] != 0x00) || (trash[1] != 0x00) ) { // It is not the end of melody // If an oscillator is available, use it if (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) { // Reset the oscillator description l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][0] = 0x0000; l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][1] = 0x0000; l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][2] = 0x0000; l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][0] = trash[0] + (trash[1] << 8); // Update the oscillators to start bit field l1s.melody_e2.global_osc_to_start |= (0x0001<<oscillator_number); // Save the oscillator as active for this melody l1s.melody0_e2.oscillator_active |= (0x0001<<oscillator_number); // oscillator is no longer available oscillator_not_available |= (0x0001<<oscillator_number); } // Download the extensions extension_index = 1; while(l1s.melody0_e2.extension_flag) { // Download the byte of the note descriptor extension l1s.melody0_e2.error_id= copy_byte_data_from_buffer (l1a_l1s_com.melody0_e2_task.parameters.session_id, &l1s.melody0_e2.buffer_size, (UWORD8 **)&l1s.melody0_e2.ptr_buf, 2, &trash[0]); // Read the extension flag l1s.melody0_e2.extension_flag = Field(trash[0], SC_MELODY_E2_EXTENSION_FLAG_MASK, SC_MELODY_E2_EXTENSION_FLAG_SHIFT); // If an oscillator is available, use it if (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) { l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][extension_index] = trash[0] + (trash[1] << 8); } extension_index++; } // extension download // find next available oscillator while( (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) && (oscillator_not_available & (0x0001<<oscillator_number)) ) { oscillator_number++; } // Read next delta time l1s.melody0_e2.error_id= copy_byte_data_from_buffer (l1a_l1s_com.melody0_e2_task.parameters.session_id, &l1s.melody0_e2.buffer_size, (UWORD8 **)&l1s.melody0_e2.ptr_buf, 1, (UWORD8 *)(&l1s.melody0_e2.counter)); // Save the extension flag l1s.melody0_e2.extension_flag = Field(l1s.melody0_e2.counter, SC_MELODY_E2_EXTENSION_FLAG_MASK, SC_MELODY_E2_EXTENSION_FLAG_SHIFT); l1s.melody0_e2.counter = Field(l1s.melody0_e2.counter, SC_MELODY_E2_DELTA_TIME_MASK, SC_MELODY_E2_DELTA_TIME_SHIFT); } // if ( (trash[0] != 0x00) || (trash[1] != 0x00) ) else { // it's the end of the melody file l1s.melody0_e2.end_of_file = TRUE; } } // while ( (l1s.melody0_e2.counter == 0) && (l1s.melody0_e2.end_of_file == FALSE) ) // Perform TDMA convertion or handle end of file if (l1s.melody0_e2.end_of_file == FALSE) { // Update note start l1s.melody0_e2.note_start_20ms += l1s.melody0_e2.counter; l1s.melody0_e2.delta_time = l1s.melody0_e2.counter; // Convert the delta time into TDMA time unit l1s.melody0_e2.counter = audio_twentyms_to_TDMA_convertion(l1s.melody0_e2.note_start_20ms) - l1s.melody_e2.timebase; // decrease the counter l1s.melody0_e2.counter--; *state = M0_WAIT_COUNTER_EQUAL_0; } else { l1s.melody0_e2.delta_time = 0xFFFF; *state = M0_WAIT_END_MELODY; } } // semaphore check } // if (l1a_l1s_com.melody0_e2_task.command.stop) (2nd else) } // case M0_WAIT_COUNTER_EQUAL_0: break; case M0_WAIT_END_MELODY: { if (l1a_l1s_com.melody0_e2_task.command.stop) { // Stop immediatly the current melody // Wait until the semaphore is set to 0 by the DSP to stop the current description if (!(l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_semaphore & SC_MELODY_E2_SEMAPHORE_MASK)) { // Stop the oscillator mentionned in the bits field melody0_e2.oscillator_active for(oscillator_number=0; oscillator_number<SC_MELODY_E2_NUMBER_OF_OSCILLATOR; oscillator_number++) { if (l1s.melody0_e2.oscillator_active & (0x0001<<oscillator_number)) { // Stop the current oscillator l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_osc_stop |= (0x0001<<oscillator_number); } } // wait until all the oscillator are stopped l1a_l1s_com.melody0_e2_task.parameters.loopback = FALSE; l1a_l1s_com.melody0_e2_task.command.stop = FALSE; l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_deltatime = 0xFFFF;// another melody could be running } // semaphore } else if (l1s.melody0_e2.oscillator_active == 0x0000) { // all oscillators are stopped if (l1a_l1s_com.melody0_e2_task.parameters.loopback) { // It's the loopback mode // Reset the pointer to the current melody #if (OP_RIV_AUDIO == 0) l1s.melody0_e2.ptr_buf = NULL; #endif l1s.melody0_e2.buffer_size = 0; l1s.melody0_e2.error_id = Cust_get_pointer((UWORD16 **)&l1s.melody0_e2.ptr_buf, &l1s.melody0_e2.buffer_size, l1a_l1s_com.melody0_e2_task.parameters.session_id); // Jump the header field l1s.melody0_e2.error_id = copy_byte_data_from_buffer (l1a_l1s_com.melody0_e2_task.parameters.session_id, &l1s.melody0_e2.buffer_size, (UWORD8 **)&l1s.melody0_e2.ptr_buf, (UWORD16)(l1a_l1s_com.melody0_e2_task.parameters.header_size), &trash[0]); // Wait until the description can be downloaded *state = M0_ALIGN_40MS_BOUNDARY; } else { // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_MELODY0_E2_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) // Go to inactive mode *state = M0_INACTIVE; } } break; } // M0_WAIT_END_MELODY } // switch } // l1s_melody0_e2_manager /*-------------------------------------------------------*/ /* l1s_melody1_e2_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Audio melody 0 format E2 L1S manager */ /* task. */ /* */ /*-------------------------------------------------------*/ void l1s_melody1_e2_manager(void) { enum states { M1_INACTIVE = 0, M1_ALIGN_40MS_BOUNDARY = 1, M1_WAIT_COUNTER_EQUAL_0 = 2, M1_WAIT_END_MELODY = 3 }; UWORD8 *state = &l1s.audio_state[L1S_MELODY1_E2_STATE]; xSignalHeaderRec *conf_msg; UWORD8 trash[SC_MELODY_E2_MAXIMUM_HEADER_SIZE+1], oscillator_number, extension_index; UWORD16 oscillator_not_available; switch(*state) { case M1_INACTIVE: { // Reset the commands: l1a_l1s_com.melody1_e2_task.command.start = FALSE; // Initialize the pointer and size to the new description l1s.melody1_e2.ptr_buf = l1a_l1s_com.melody1_e2_task.parameters.ptr_buf; l1s.melody1_e2.buffer_size = l1a_l1s_com.melody1_e2_task.parameters.buffer_size; *state = M1_ALIGN_40MS_BOUNDARY; } break; case M1_ALIGN_40MS_BOUNDARY: { // Initialize the counter to the first time l1s.melody1_e2.error_id = copy_byte_data_from_buffer (l1a_l1s_com.melody1_e2_task.parameters.session_id, &l1s.melody1_e2.buffer_size, (UWORD8 **)&l1s.melody1_e2.ptr_buf, 1, (UWORD8 *)(&l1s.melody1_e2.counter)); // Save the extension flag l1s.melody1_e2.extension_flag = Field(l1s.melody1_e2.counter, SC_MELODY_E2_EXTENSION_FLAG_MASK, SC_MELODY_E2_EXTENSION_FLAG_SHIFT); // Save delta-time in 20ms unit l1s.melody1_e2.counter = Field(l1s.melody1_e2.counter, SC_MELODY_E2_DELTA_TIME_MASK, SC_MELODY_E2_DELTA_TIME_SHIFT); l1s.melody1_e2.note_start_20ms = l1s.melody1_e2.counter; // Adjust note_start on 20ms boundary because global counter could be running for another melody or loopback // Timebase can be computed as k*60ms + timebase_mod_60ms l1s.melody1_e2.note_start_20ms += ((l1s.melody_e2.timebase - l1s.melody_e2.timebase_mod_60ms) / 13 * 3); if (l1s.melody_e2.timebase_mod_60ms < 4) { l1s.melody1_e2.note_start_20ms += 1; } else if (l1s.melody_e2.timebase_mod_60ms < 8) { l1s.melody1_e2.note_start_20ms += 2; } else if (l1s.melody_e2.timebase_mod_60ms < 13) { l1s.melody1_e2.note_start_20ms += 3; } // Align on 40ms boundary if ( (l1s.melody1_e2.note_start_20ms & 1) == 1 ) l1s.melody1_e2.note_start_20ms++; // Convert to TDMA l1s.melody1_e2.counter = audio_twentyms_to_TDMA_convertion(l1s.melody1_e2.note_start_20ms); // Compute TDMA to wait (-1 to take into account this TDMA) l1s.melody1_e2.counter = l1s.melody1_e2.counter - l1s.melody_e2.timebase - 1; // Wait to download the first description *state = M1_WAIT_COUNTER_EQUAL_0; } // M1_INIT break; case M1_WAIT_COUNTER_EQUAL_0: { // Stop command if (l1a_l1s_com.melody1_e2_task.command.stop) { // wait until all the ocillator are stopped *state = M1_WAIT_END_MELODY; } else if (l1s.melody1_e2.counter > 0) { // Decrease the counter l1s.melody1_e2.counter--; } else { // Wait until the semaphore is set to 0 by the DSP if (!(l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_semaphore & SC_MELODY_E2_SEMAPHORE_MASK)) { // Initialize oscillators available, oscillators can be used by the DSP (d_melody_e2_osc_active) // or by the other melody E2 generator (melody_e2_osc_stop) oscillator_not_available = l1s.melody_e2.global_osc_active | l1s.melody_e2.global_osc_to_start; // find an available oscillator oscillator_number = 0; while( (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) && (oscillator_not_available & (0x0001<<oscillator_number)) ) { oscillator_number++; } // Initialize end of file l1s.melody1_e2.end_of_file = FALSE; // download the description until the delta time is different from 0 // or end of the melody file while ( (l1s.melody1_e2.counter == 0) && (l1s.melody1_e2.end_of_file == FALSE) ) { // Download the byte of the note descriptor extension in trash l1s.melody1_e2.error_id= copy_byte_data_from_buffer (l1a_l1s_com.melody1_e2_task.parameters.session_id, &l1s.melody1_e2.buffer_size, (UWORD8 **)&l1s.melody1_e2.ptr_buf, 2, &trash[0]); // Check end of melody if ( (trash[0] != 0x00) || (trash[1] != 0x00) ) { // It is not the end of melody // If an oscillator is available, use it if (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) { // Reset the oscillator description l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][0] = 0x0000; l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][1] = 0x0000; l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][2] = 0x0000; l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][0] = trash[0] + (trash[1] << 8); // Update the oscillators to start bit field l1s.melody_e2.global_osc_to_start |= (0x0001<<oscillator_number); // Save the oscillator as active for this melody l1s.melody1_e2.oscillator_active |= (0x0001<<oscillator_number); // oscillator is no longer available oscillator_not_available |= (0x0001<<oscillator_number); } // Download the extensions extension_index = 1; while(l1s.melody1_e2.extension_flag) { // Download the byte of the note descriptor extension l1s.melody1_e2.error_id= copy_byte_data_from_buffer (l1a_l1s_com.melody1_e2_task.parameters.session_id, &l1s.melody1_e2.buffer_size, (UWORD8 **)&l1s.melody1_e2.ptr_buf, 2, &trash[0]); // Read the extension flag l1s.melody1_e2.extension_flag = Field(trash[0], SC_MELODY_E2_EXTENSION_FLAG_MASK, SC_MELODY_E2_EXTENSION_FLAG_SHIFT); // If an oscillator is available, use it if (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) { l1s_dsp_com.dsp_ndb_ptr->a_melody_e2_osc[oscillator_number][extension_index] = trash[0] + (trash[1] << 8); } extension_index++; } // extension download // find next available oscillator while( (oscillator_number < SC_MELODY_E2_NUMBER_OF_OSCILLATOR) && (oscillator_not_available & (0x0001<<oscillator_number)) ) { oscillator_number++; } // Read next delta time l1s.melody1_e2.error_id= copy_byte_data_from_buffer (l1a_l1s_com.melody1_e2_task.parameters.session_id, &l1s.melody1_e2.buffer_size, (UWORD8 **)&l1s.melody1_e2.ptr_buf, 1, (UWORD8 *)(&l1s.melody1_e2.counter)); // Save the extension flag l1s.melody1_e2.extension_flag = Field(l1s.melody1_e2.counter, SC_MELODY_E2_EXTENSION_FLAG_MASK, SC_MELODY_E2_EXTENSION_FLAG_SHIFT); l1s.melody1_e2.counter = Field(l1s.melody1_e2.counter, SC_MELODY_E2_DELTA_TIME_MASK, SC_MELODY_E2_DELTA_TIME_SHIFT); } // if ( (trash[0] != 0x00) || (trash[1] != 0x00) ) else { // it's the end of the melody file l1s.melody1_e2.end_of_file = TRUE; } } // while ( (l1s.melody1_e2.counter == 0) && (l1s.melody1_e2.end_of_file == FALSE) ) // Perform TDMA convertion or handle end of file if (l1s.melody1_e2.end_of_file == FALSE) { // Update note start l1s.melody1_e2.note_start_20ms += l1s.melody1_e2.counter; l1s.melody1_e2.delta_time = l1s.melody1_e2.counter; // Convert the delta time into TDMA time unit l1s.melody1_e2.counter = audio_twentyms_to_TDMA_convertion(l1s.melody1_e2.note_start_20ms) - l1s.melody_e2.timebase; // decrease the counter l1s.melody1_e2.counter--; *state = M1_WAIT_COUNTER_EQUAL_0; } else { l1s.melody1_e2.delta_time = 0xFFFF; *state = M1_WAIT_END_MELODY; } } // semaphore check } // if (l1a_l1s_com.melody1_e2_task.command.stop) (2nd else) } // case M1_WAIT_COUNTER_EQUAL_0: break; case M1_WAIT_END_MELODY: { if (l1a_l1s_com.melody1_e2_task.command.stop) { // Stop immediatly the current melody // Wait until the semaphore is set to 0 by the DSP to stop the current description if (!(l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_semaphore & SC_MELODY_E2_SEMAPHORE_MASK)) { // Stop the oscillator mentionned in the bits field melody1_e2.oscillator_active for(oscillator_number=0; oscillator_number<SC_MELODY_E2_NUMBER_OF_OSCILLATOR; oscillator_number++) { if (l1s.melody1_e2.oscillator_active & (0x0001<<oscillator_number)) { // Stop the current oscillator l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_osc_stop |= (0x0001<<oscillator_number); } } // wait until all the oscillator are stopped l1a_l1s_com.melody1_e2_task.parameters.loopback = FALSE; l1a_l1s_com.melody1_e2_task.command.stop = FALSE; l1s_dsp_com.dsp_ndb_ptr->d_melody_e2_deltatime = 0xFFFF; // another melody could be running } // semaphore } else if (l1s.melody1_e2.oscillator_active == 0x0000) { // all oscillators are stopped if (l1a_l1s_com.melody1_e2_task.parameters.loopback) { // It's the loopback mode // Reset the pointer to the current melody #if (OP_RIV_AUDIO == 0) l1s.melody1_e2.ptr_buf = NULL; #endif l1s.melody1_e2.buffer_size = 0; l1s.melody1_e2.error_id = Cust_get_pointer((UWORD16 **)&l1s.melody1_e2.ptr_buf, &l1s.melody1_e2.buffer_size, l1a_l1s_com.melody1_e2_task.parameters.session_id); // Jump the header field l1s.melody1_e2.error_id = copy_byte_data_from_buffer (l1a_l1s_com.melody1_e2_task.parameters.session_id, &l1s.melody1_e2.buffer_size, (UWORD8 **)&l1s.melody1_e2.ptr_buf, (UWORD16)(l1a_l1s_com.melody1_e2_task.parameters.header_size), &trash[0]); // Wait until the description can be downloaded *state = M1_ALIGN_40MS_BOUNDARY; } else { // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_MELODY1_E2_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) // Go to inactive mode *state = M1_INACTIVE; } } break; } // M1_WAIT_END_MELODY } // switch } // l1s_melody1_e2_manager #endif // MELODY_E2 #if (L1_CPORT == 1) /*-------------------------------------------------------*/ /* l1s_cport_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Cport L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_cport_manager(void) { enum states { IDLE = 0, WAIT_CPORT_CONF = 1 }; UWORD8 *state = &l1s.audio_state[L1S_CPORT_STATE]; xSignalHeaderRec *conf_msg; API temp_write_var; switch(*state) { case IDLE: { // Check if a cport configuration is not yet in progress in DSP if (l1s_dsp_com.dsp_ndb_ptr->d_cport_status == (API) (CPORT_R_NONE | CPORT_W_NONE)) { // ok, we can start the DSP Cport configuration task if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CTRL) l1s_dsp_com.dsp_ndb_ptr->d_cport_ctrl = l1a_l1s_com.cport_task.parameters.ctrl; if (l1a_l1s_com.cport_task.parameters.configuration & (CPORT_W_CPCFR1 | CPORT_W_CPCFR2)) { temp_write_var = 0; if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPCFR1) temp_write_var = l1a_l1s_com.cport_task.parameters.cpcfr1 << 8; if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPCFR2) temp_write_var |= l1a_l1s_com.cport_task.parameters.cpcfr2; l1s_dsp_com.dsp_ndb_ptr->a_cport_cfr[0] = temp_write_var; } if (l1a_l1s_com.cport_task.parameters.configuration & (CPORT_W_CPCFR3 | CPORT_W_CPCFR4)) { temp_write_var = 0; if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPCFR3) temp_write_var = l1a_l1s_com.cport_task.parameters.cpcfr3 << 8; if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPCFR4) temp_write_var |= l1a_l1s_com.cport_task.parameters.cpcfr4; l1s_dsp_com.dsp_ndb_ptr->a_cport_cfr[1] = temp_write_var; } if (l1a_l1s_com.cport_task.parameters.configuration & (CPORT_W_CPTCTL | CPORT_W_CPTTADDR)) { temp_write_var = 0; if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPTCTL) temp_write_var = l1a_l1s_com.cport_task.parameters.cptctl << 8; if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPTTADDR) temp_write_var |= l1a_l1s_com.cport_task.parameters.cpttaddr; l1s_dsp_com.dsp_ndb_ptr->d_cport_tcl_tadt = temp_write_var; } if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPTDAT) l1s_dsp_com.dsp_ndb_ptr->d_cport_tdat = l1a_l1s_com.cport_task.parameters.cptdat; if (l1a_l1s_com.cport_task.parameters.configuration & CPORT_W_CPTVS) l1s_dsp_com.dsp_ndb_ptr->d_cport_tvs = l1a_l1s_com.cport_task.parameters.cptvs; l1s_dsp_com.dsp_ndb_ptr->d_cport_init = l1a_l1s_com.cport_task.parameters.configuration; *state = WAIT_CPORT_CONF; // Reset the command l1a_l1s_com.cport_task.command.start = FALSE; } // else, we do nothing -> check will be done again at next frame } break; case WAIT_CPORT_CONF: { // the DSP acknowledges the L1S start request. if (l1s_dsp_com.dsp_ndb_ptr->d_cport_init == l1s_dsp_com.dsp_ndb_ptr->d_cport_status) { // task is over l1s_dsp_com.dsp_ndb_ptr->d_cport_init = (API) (CPORT_R_NONE | CPORT_W_NONE); l1s_dsp_com.dsp_ndb_ptr->d_cport_ctrl = (API) 0; l1s_dsp_com.dsp_ndb_ptr->a_cport_cfr[0] = (API) 0; l1s_dsp_com.dsp_ndb_ptr->a_cport_cfr[1] = (API) 0; l1s_dsp_com.dsp_ndb_ptr->d_cport_tcl_tadt = (API) 0; l1s_dsp_com.dsp_ndb_ptr->d_cport_tdat = (API) 0; l1s_dsp_com.dsp_ndb_ptr->d_cport_tvs = (API) 0; // Send the configuration confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(sizeof(T_L1_CPORT_CONFIGURE_CON)); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_CPORT_CONFIGURE_CON; //Fill the message ((T_L1_CPORT_CONFIGURE_CON *)(conf_msg->SigP))->register_id = (l1s_dsp_com.dsp_ndb_ptr->d_cport_status & CPORT_READ_MASK); ((T_L1_CPORT_CONFIGURE_CON *)(conf_msg->SigP))->register_value = l1s_dsp_com.dsp_ndb_ptr->d_cport_reg_value; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_CPORT == 1 #if 0 /* FreeCalypso: function not present in TCS211 */ /*-------------------------------------------------------*/ /* l1s_audio_it_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Audio it manager */ /* */ /*-------------------------------------------------------*/ void l1s_audio_it_manager(void) { // Reset the command : l1a_l1s_com.audioIt_task.command.start = FALSE; // this is an empty state machin only used to generate an // audio IT to DSP in case another sw entity has changed // something in the API } #endif #if (L1_EXTERNAL_AUDIO_VOICE_ONOFF == 1) /*-------------------------------------------------------*/ /* l1s_audio_onoff_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : audio on/off L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_audio_onoff_manager(void) { enum states { IDLE = 0, WAIT_AUDIO_ONOFF_CON = 1 }; UWORD8 *state = &l1s.audio_state[L1S_AUDIO_ONOFF_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Disable the start command l1a_l1s_com.audio_onoff_task.command.start = FALSE; // Update the audio on/off value except if the L1S is already forcing it if ((l1a_l1s_com.audio_onoff_task.parameters.onoff_value == TRUE) && (l1a_l1s_com.audio_forced_by_l1s == FALSE)) // l1a_l1s_com.audio_onoff_task.parameters.onoff_value == AUDIO_ON { l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (API) B_AUDIO_ON_START; } else if ((l1a_l1s_com.audio_onoff_task.parameters.onoff_value == FALSE) && (l1a_l1s_com.audio_forced_by_l1s == FALSE)) // l1a_l1s_com.audio_onoff_task.parameters.onoff_value == AUDIO_OFF { l1s_dsp_com.dsp_ndb_ptr->d_toneskb_init |= (API) B_AUDIO_OFF_STOP; } *state = WAIT_AUDIO_ONOFF_CON; } break; case WAIT_AUDIO_ONOFF_CON: { // The L1 has to send the confirmation message even if the request was to disable the audio on/off // and it is still forced. This confirmation message is only to acknowledge the reception of the message, // it is not correlated to the state of the audio into the DSP. // Allocate memory for confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AUDIO_ONOFF_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } break; } // switch } #endif #if (L1_EXT_MCU_AUDIO_VOICE_ONOFF == 1) /*-------------------------------------------------------*/ /* l1s_audio_onoff_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : audio on/off L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_audio_voice_onoff_manager(void) { enum states { IDLE = 0, WAIT_AUDIO_ONOFF_CON = 1 }; UWORD8 *state = &l1s.audio_state[L1S_AUDIO_ONOFF_STATE]; UWORD8 *ul_state = &l1s.audio_state[L1S_AUDIO_UL_ONOFF_STATE]; UWORD8 *dl_state = &l1s.audio_state[L1S_AUDIO_DL_ONOFF_STATE]; UWORD8 *vul_state = &l1a_l1s_com.audio_onoff_task.parameters.vul_onoff_value; UWORD8 *vdl_state = &l1a_l1s_com.audio_onoff_task.parameters.vdl_onoff_value; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { // Disable the start command l1a_l1s_com.audio_onoff_task.command.start = FALSE; // Update the Voice Uplink count if(l1a_l1s_com.audio_onoff_task.parameters.vul_onoff_value == L1_AUDIO_VOICE_UL_ON) { l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request++; } else if(l1a_l1s_com.audio_onoff_task.parameters.vul_onoff_value == L1_AUDIO_VOICE_UL_OFF ) { if(l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request) l1s.audio_on_off_ctl.l1_audio_switch_on_ul_request--; } // Update the Voice Downlink count if(l1a_l1s_com.audio_onoff_task.parameters.vdl_onoff_value == L1_AUDIO_VOICE_DL_ON) { l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request++; } else if(l1a_l1s_com.audio_onoff_task.parameters.vdl_onoff_value == L1_AUDIO_VOICE_DL_OFF) { if(l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request) l1s.audio_on_off_ctl.l1_audio_switch_on_dl_request--; } *state = WAIT_AUDIO_ONOFF_CON; } break; case WAIT_AUDIO_ONOFF_CON: { // For Voice Uplink or Downlink switch on is done only after the VUL or VDL is actually switched ON // For switch off there could be potentially other tasks that use the VUL or VDL and hence a blind // confirmation is given if( (((*vul_state == L1_AUDIO_VOICE_UL_ON) && (*ul_state == L1_AUDIO_UL_ON)) || (*vul_state == L1_AUDIO_VOICE_UL_OFF) || (*vul_state == L1_AUDIO_VOICE_UL_NO_ACTION)) && (((*vdl_state == L1_AUDIO_VOICE_DL_ON) && (*dl_state == L1_AUDIO_DL_ON)) || (*vdl_state == L1_AUDIO_VOICE_DL_OFF) || (*vdl_state == L1_AUDIO_VOICE_DL_NO_ACTION))) { // The L1 has to send the confirmation message even if the request was to disable the audio on/off // and it is still forced. This confirmation message is only to acknowledge the reception of the message, // it is not correlated to the state of the audio into the DSP. // Allocate memory for confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AUDIO_ONOFF_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif #if (L1_STEREOPATH == 1) /*-------------------------------------------------------*/ /* l1s_stereopath_drv_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : Generic Stereopath L1S manager task. */ /* */ /*-------------------------------------------------------*/ #if (CODE_VERSION == SIMULATION) void l1s_stereopath_drv_manager(void) { enum states { IDLE=0, WAIT_STOP }; xSignalHeaderRec *conf_msg; if(l1a_l1s_com.stereopath_drv_task.command.start==TRUE) { // reset the command l1a_l1s_com.stereopath_drv_task.command.start=FALSE; // change state l1s.audio_state[L1S_STEREOPATH_DRV_STATE]=WAIT_STOP; // send confirmation to the L1A conf_msg=os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode=L1_STEREOPATH_DRV_START_CON; os_send_sig(conf_msg,L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } if(l1a_l1s_com.stereopath_drv_task.command.stop==TRUE) { // reset the command l1a_l1s_com.stereopath_drv_task.command.stop=FALSE; // change state l1s.audio_state[L1S_STEREOPATH_DRV_STATE]=IDLE; // send confirmation to the L1A conf_msg=os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode=L1_STEREOPATH_DRV_STOP_CON; os_send_sig(conf_msg,L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } #else // CODE_VERSION void l1s_stereopath_drv_manager(void) { //sundi: change in the enum values for the ABB states #if (ANLG_FAM == 11) enum states { IDLE = 0, ABB_CONFIGURE_DONE = 1, ABB_START = 2, ABB_START_DONE = 3, DMA_CONF = 4, CPORT_CONF = 5, CPORT_START = 6, WAIT_STOP = 7, CPORT_STOP = 8, ABB_STOP_DONE = 9, DMA_STOP = 10, STOP_CON = 11 }; #else enum states { IDLE = 0, ABB_START = 1, DMA_CONF = 2, CPORT_CONF = 3, CPORT_START = 4, WAIT_STOP = 5, CPORT_STOP = 6, DMA_STOP = 7, STOP_CON = 8 }; #endif UWORD8 *state = &l1s.audio_state[L1S_STEREOPATH_DRV_STATE]; xSignalHeaderRec *conf_msg; static UWORD16 wait_pll_on_counter = L1S_STEREOPATH_DRV_WAIT_PLL_COUNTER; // This is the default parameters structure for a DMA channel static T_DMA_TYPE_CHANNEL_PARAMETER d_dma_channel_parameter= { f_dma_default_call_back_it, // call back function C_DMA_CHANNEL_2, // channel number C_DMA_CHANNEL_NOT_SECURED, // channel security C_DMA_DATA_S16, // data type C_DMA_IMIF_PORT, // source port C_DMA_CHANNEL_NOT_PACKED, // source packing C_DMA_CHANNEL_SINGLE, // source bursting C_DMA_RHEA_PORT, // destination port C_DMA_CHANNEL_NOT_PACKED, // destination packing C_DMA_CHANNEL_SINGLE, // destination bursting C_DMA_CHANNEL_CPORT_TX, // hw synchro C_DMA_CHANNEL_PRIORITY_HIGH, // channel priority C_DMA_CHANNEL_AUTO_INIT_ON, // autoinit option C_DMA_CHANNEL_FIFO_FLUSH_OFF, // fifo flush option C_DMA_CHANNEL_ADDR_MODE_POST_INC, // source addressing mode C_DMA_CHANNEL_ADDR_MODE_CONSTANT, // destination addressing mode C_DMA_CHANNEL_IT_TIME_OUT_ON, // IT time out control C_DMA_CHANNEL_IT_DROP_ON, // IT drop control C_DMA_CHANNEL_IT_FRAME_OFF, // IT frame control C_DMA_CHANNEL_IT_BLOCK_ON, // IT block control C_DMA_CHANNEL_IT_HALF_BLOCK_ON, // IT half_block control 0, // source start address 0xFFFFD800L, // destination start address 2, // element number 0 // frame number }; switch(*state) { case IDLE: { #if (ANLG_FAM == 11) //Sundi:Set the abb_write_done variable to 0. This variable gets set in I2C call back fn. l1s.abb_write_done = 0; #endif // Configure the ABB audio part in order to get the correct clock for the Cport l1s_stereopath_drv_config_ABB(l1a_l1s_com.stereopath_drv_task.parameters.mono_stereo, l1a_l1s_com.stereopath_drv_task.parameters.sampling_frequency); #if (ANLG_FAM == 11) // Must wait for the PLL to be locked. The value of 1 is subtracted from the standard value // in order to take care of the extra state added - ABB_CONFIGURE_DONE. wait_pll_on_counter = L1S_STEREOPATH_DRV_WAIT_PLL_COUNTER - 1; #else // Must wait for the PLL to be locked. wait_pll_on_counter = L1S_STEREOPATH_DRV_WAIT_PLL_COUNTER; #endif // Reset the command l1a_l1s_com.stereopath_drv_task.command.start = FALSE; #if (ANLG_FAM == 11) //sundi: change the state to ABB_CONFIGURE_DONE to wait for I2C write ACK. *state = ABB_CONFIGURE_DONE; #else *state = ABB_START; #endif } break; #if (ANLG_FAM == 11) //sundi: add the new state case ABB_CONFIGURE_DONE: { //sundi: continue to be in this state till an I2C write ACK comes. //abb_write_done is set to 1 by the call back function //that is passed to the I2C write function. if (l1s.abb_write_done == 1) { *state = ABB_START; } } break; #endif case ABB_START: { if (wait_pll_on_counter == 0) { #if (ANLG_FAM == 11) //Sundi:Set the abb_write_done variable to 0. This variable gets set in I2C call back fn. l1s.abb_write_done = 0; #endif // PLL is locked, the ABB can be started l1s_stereopath_drv_start_ABB(); #if (ANLG_FAM == 11) //sundi: Change state to ABB_START_DONE *state = ABB_START_DONE; #else *state = DMA_CONF; #endif } else wait_pll_on_counter--; } break; #if (ANLG_FAM == 11) //sundi: Add the new state ABB_START_DONE case ABB_START_DONE: { //sundi: continue to be in this state till an I2C write ACK comes. //abb_write_done is set to 1 by the call back function //that is passed to the I2C write function. if (l1s.abb_write_done == 1) { *state = DMA_CONF; } } break; #endif // After 1 TDMA frame, DSP has necessarily programmed ABB case DMA_CONF: { // update the DMA defaut parameters structure with received parameters d_dma_channel_parameter.pf_dma_call_back_address = (T_DMA_CALL_BACK) l1a_l1s_com.stereopath_drv_task.parameters.DMA_int_callback_fct; d_dma_channel_parameter.d_dma_channel_number = (T_DMA_TYPE_CHANNEL_NUMBER) l1a_l1s_com.stereopath_drv_task.parameters.DMA_channel_number; d_dma_channel_parameter.d_dma_channel_data_type = (T_DMA_TYPE_CHANNEL_DATA_TYPE) l1a_l1s_com.stereopath_drv_task.parameters.data_type; d_dma_channel_parameter.d_dma_channel_src_port = (T_DMA_TYPE_CHANNEL_PORT) l1a_l1s_com.stereopath_drv_task.parameters.source_port; d_dma_channel_parameter.d_dma_channel_src_address = (SYS_UWORD32) l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address; d_dma_channel_parameter.d_dma_channel_element_number = (SYS_UWORD16) l1a_l1s_com.stereopath_drv_task.parameters.element_number; d_dma_channel_parameter.d_dma_channel_frame_number = (SYS_UWORD16) l1a_l1s_com.stereopath_drv_task.parameters.frame_number; // Configure and start the DMA channel l1s_stereopath_drv_start_DMA(d_dma_channel_parameter,l1a_l1s_com.stereopath_drv_task.parameters.DMA_allocation); // Reset the Cport l1s_stereopath_drv_reset_CPORT(); *state = CPORT_CONF; } break; case CPORT_CONF: { // Configure the Cport l1s_stereopath_drv_config_CPORT(); *state = CPORT_START; } break; case CPORT_START: { // Start the Cport l1s_stereopath_drv_start_CPORT(); // Send the start confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_STEREOPATH_DRV_START_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = WAIT_STOP; } break; case WAIT_STOP: { /* OUTEN registers have been updated */ if(l1a_l1s_com.outen_cfg_task.command_requested != l1a_l1s_com.outen_cfg_task.command_commited) { l1s_stereopath_callback(L1S_TWL3029_STEROPATH_START); } if (l1a_l1s_com.stereopath_drv_task.command.stop) { // Stop command received // Reset the Cport l1s_stereopath_drv_reset_CPORT(); *state = CPORT_STOP; // Disable the stop command l1a_l1s_com.stereopath_drv_task.command.stop = FALSE; } } break; case CPORT_STOP: { // Stop the Cport l1s_stereopath_drv_stop_CPORT(); #if (ANLG_FAM == 11) //Set the abb_write_done variable to 0. This variable gets set in I2C call back fn. l1s.abb_write_done = 0; #endif // Stop the ABB l1s_stereopath_drv_stop_ABB(); #if (ANLG_FAM == 11) //sundi: change state to ABB_STOP_DONE *state = ABB_STOP_DONE; #else *state = DMA_STOP; #endif } break; #if (ANLG_FAM == 11) //sundi: Add a new state ABB_STOP_DONE case ABB_STOP_DONE: { //sundi:continue to be in this state till an I2C write ACK comes. //abb_write_done is set to 1 by the call back function //that is passed to the I2C write function. if (l1s.abb_write_done == 1) { *state = DMA_STOP; } } break; #endif case DMA_STOP: { // Reset the DMA channel l1s_stereopath_drv_reset_DMA(d_dma_channel_parameter); *state = STOP_CON; } break; case STOP_CON: { // Send the stop confirmation message // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_STEREOPATH_DRV_STOP_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR); *state = IDLE; } break; } // switch } #endif // CODE_VERSION #endif // L1_STEREOPATH == 1 #if (L1_ANR == 1) /*-------------------------------------------------------*/ /* l1s_anr_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : ANR L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_anr_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_ANR_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.anr_task.parameters.anr_enable) { // ANR start requested //-------------------- // Set ANR parameters l1s_dsp_com.dsp_ndb_ptr->d_anr_min_gain = l1a_l1s_com.anr_task.parameters.min_gain; l1s_dsp_com.dsp_ndb_ptr->d_anr_div_factor_shift = l1a_l1s_com.anr_task.parameters.div_factor_shift; l1s_dsp_com.dsp_ndb_ptr->d_anr_ns_level = l1a_l1s_com.anr_task.parameters.ns_level; #if (DSP == 38) || (DSP == 39) if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ANR_UL_STATE) #else if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ANR_STATE) #endif { // ANR already started: update the DSP ANR module l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl = B_ANR_FULL_UPDATE; *state = WAIT_DSP_ACK; } else { // Set ANR constants l1s_dsp_com.dsp_ndb_ptr->d_anr_vad_thr = C_ANR_VAD_THR; l1s_dsp_com.dsp_ndb_ptr->d_anr_gamma_slow = C_ANR_GAMMA_SLOW; l1s_dsp_com.dsp_ndb_ptr->d_anr_gamma_fast = C_ANR_GAMMA_FAST; l1s_dsp_com.dsp_ndb_ptr->d_anr_gamma_gain_slow = C_ANR_GAMMA_GAIN_SLOW; l1s_dsp_com.dsp_ndb_ptr->d_anr_gamma_gain_fast = C_ANR_GAMMA_GAIN_FAST; l1s_dsp_com.dsp_ndb_ptr->d_anr_thr2 = C_ANR_THR2; l1s_dsp_com.dsp_ndb_ptr->d_anr_thr4 = C_ANR_THR4; l1s_dsp_com.dsp_ndb_ptr->d_anr_thr5 = C_ANR_THR5; l1s_dsp_com.dsp_ndb_ptr->d_anr_mean_ratio_thr1 = C_ANR_MEAN_RATIO_THR1; l1s_dsp_com.dsp_ndb_ptr->d_anr_mean_ratio_thr2 = C_ANR_MEAN_RATIO_THR2; l1s_dsp_com.dsp_ndb_ptr->d_anr_mean_ratio_thr3 = C_ANR_MEAN_RATIO_THR3; l1s_dsp_com.dsp_ndb_ptr->d_anr_mean_ratio_thr4 = C_ANR_MEAN_RATIO_THR4; // Enable the DSP ANR module l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl = B_ANR_ENABLE; *state = WAIT_DSP_ACK; } } else // ANR start requested { // ANR stop requested //------------------- #if (DSP == 38) || (DSP == 39) if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ANR_UL_STATE) #else if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ANR_STATE) #endif { // Disable the DSP ANR module l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl = B_ANR_DISABLE; *state = WAIT_DSP_ACK; } else { // ANR already disabled: confirm // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_ANR_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.anr_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_ANR_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_ANR == 1 #if (L1_ANR == 2) /*-------------------------------------------------------*/ /* l1s_anr_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : ANR 2.13 L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_anr_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_ANR_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.anr_task.parameters.anr_ul_control == ANR_START || l1a_l1s_com.anr_task.parameters.anr_ul_control == ANR_UPDATE ) { // ANR start or update requested //------------------------------ // Set ANR parameters l1s_dsp_com.dsp_ndb_ptr->d_anr_control = l1a_l1s_com.anr_task.parameters.control; l1s_dsp_com.dsp_ndb_ptr->d_anr_ns_level = l1a_l1s_com.anr_task.parameters.ns_level; l1s_dsp_com.dsp_ndb_ptr->d_anr_tone_ene_th = l1a_l1s_com.anr_task.parameters.tone_ene_th; l1s_dsp_com.dsp_ndb_ptr->d_anr_tone_cnt_th = l1a_l1s_com.anr_task.parameters.tone_cnt_th; if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ANR_UL_STATE) { // ANR already started: update the DSP ANR module l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl = B_ANR_FULL_UPDATE; l1s.anr_ul_action = ANR_UPDATED; *state = WAIT_DSP_ACK; } else { // Enable the DSP ANR module l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl = B_ANR_ENABLE; l1s.anr_ul_action = ANR_STARTED; *state = WAIT_DSP_ACK; } } if (l1a_l1s_com.anr_task.parameters.anr_ul_control == ANR_STOP) { // ANR stop requested //------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ANR_UL_STATE) { // Disable the DSP ANR module l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl = B_ANR_DISABLE; l1s.anr_ul_action = ANR_STOPPED; *state = WAIT_DSP_ACK; } else { // ANR already disabled: confirm // Allocate confirmation message... l1s.anr_ul_action = ANR_NO_ACTION; conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_ANR_CON; ((T_L1_AQI_ANR_CON *)(conf_msg->SigP))->anr_ul_action = l1s.anr_ul_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.anr_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_anr_ul_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_ANR_CON; ((T_L1_AQI_ANR_CON *)(conf_msg->SigP))->anr_ul_action = l1s.anr_ul_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_ANR == 2 #if (L1_IIR == 1) /*-------------------------------------------------------*/ /* l1s_iir_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : IIR L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_iir_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_IIR_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.iir_task.parameters.iir_enable) { UWORD8 i; // IIR start requested //-------------------- // Set IIR parameters l1s_dsp_com.dsp_ndb_ptr->d_iir_nb_iir_blocks = l1a_l1s_com.iir_task.parameters.nb_iir_blocks; for (i=0; i < (l1a_l1s_com.iir_task.parameters.nb_iir_blocks * 8); i++) l1s_dsp_com.dsp_ndb_ptr->a_iir_iir_coefs[i] = l1a_l1s_com.iir_task.parameters.iir_coefs[i]; l1s_dsp_com.dsp_ndb_ptr->d_iir_nb_fir_coefs = l1a_l1s_com.iir_task.parameters.nb_fir_coefs; for (i=0; i < l1a_l1s_com.iir_task.parameters.nb_fir_coefs; i++) l1s_dsp_com.dsp_ndb_ptr->a_iir_fir_coefs[i] = l1a_l1s_com.iir_task.parameters.fir_coefs[i]; l1s_dsp_com.dsp_ndb_ptr->d_iir_input_scaling = l1a_l1s_com.iir_task.parameters.input_scaling; l1s_dsp_com.dsp_ndb_ptr->d_iir_fir_scaling = l1a_l1s_com.iir_task.parameters.fir_scaling; l1s_dsp_com.dsp_ndb_ptr->d_iir_input_gain_scaling = l1a_l1s_com.iir_task.parameters.input_gain_scaling; l1s_dsp_com.dsp_ndb_ptr->d_iir_output_gain_scaling = l1a_l1s_com.iir_task.parameters.output_gain_scaling; l1s_dsp_com.dsp_ndb_ptr->d_iir_output_gain = l1a_l1s_com.iir_task.parameters.output_gain; l1s_dsp_com.dsp_ndb_ptr->d_iir_feedback = l1a_l1s_com.iir_task.parameters.feedback; #if (DSP == 38) || (DSP == 39) if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_IIR_DL_STATE) #else if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_IIR_STATE) #endif { // IIR already started: update the DSP IIR module l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl = B_IIR_FULL_UPDATE; *state = WAIT_DSP_ACK; } else { // Enable the DSP IIR module l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl = B_IIR_ENABLE; *state = WAIT_DSP_ACK; } } else // IIR start requested { // IIR stop requested //------------------- #if (DSP == 38) || (DSP == 39) if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_IIR_DL_STATE) #else if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_IIR_STATE) #endif { // Disable the DSP IIR module l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl = B_IIR_DISABLE; *state = WAIT_DSP_ACK; } else { // IIR already disabled: confirm // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_IIR_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.iir_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_IIR_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_IIR == 1 #if (L1_AGC_UL == 1) /*-------------------------------------------------------*/ /* l1s_agc_ul_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : AGC_UL L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_agc_ul_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_AGC_UL_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.agc_ul_task.parameters.agc_ul_control == AGC_START || l1a_l1s_com.agc_ul_task.parameters.agc_ul_control == AGC_UPDATE) { // AGC_UL start or update requested //--------------------------------- // Set AGC UL parameters l1_audio_agc_ul_copy_params(); if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_AGC_UL_STATE) { // AGC UL already started: update the DSP AGC UL module l1s_dsp_com.dsp_ndb_ptr->d_agc_ul_ctrl = B_AGC_FULL_UPDATE; l1s.agc_ul_action = AGC_UPDATED; *state = WAIT_DSP_ACK; } else { // Enable the DSP AGC UL module l1s_dsp_com.dsp_ndb_ptr->d_agc_ul_ctrl = B_AGC_ENABLE; l1s.agc_ul_action = AGC_STARTED; *state = WAIT_DSP_ACK; } } if (l1a_l1s_com.agc_ul_task.parameters.agc_ul_control == AGC_STOP) { // AGC UL stop requested //------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_AGC_UL_STATE) { // Disable the DSP AGC UL module l1s_dsp_com.dsp_ndb_ptr->d_agc_ul_ctrl = B_AGC_DISABLE; l1s.agc_ul_action = AGC_STOPPED; *state = WAIT_DSP_ACK; } else { // AGC UL already disabled: confirm // Allocate confirmation message... l1s.agc_ul_action = AGC_NO_ACTION; conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_AGC_UL_CON; ((T_L1_AQI_AGC_UL_CON *)(conf_msg->SigP))->agc_ul_action = l1s.agc_ul_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.agc_ul_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_agc_ul_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_AGC_UL_CON; ((T_L1_AQI_AGC_UL_CON *)(conf_msg->SigP))->agc_ul_action = l1s.agc_ul_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_AGC_UL == 1 #if (L1_AGC_DL == 1) /*-------------------------------------------------------*/ /* l1s_agc_dl_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : AGC DL L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_agc_dl_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_AGC_DL_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.agc_dl_task.parameters.agc_dl_control == AGC_START || l1a_l1s_com.agc_dl_task.parameters.agc_dl_control == AGC_UPDATE) { // AGC DL start or update requested //--------------------------------- // Set AGC DL parameters l1_audio_agc_dl_copy_params(); if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_AGC_DL_STATE) { // AGC DL already started: update the DSP AGC DL module l1s_dsp_com.dsp_ndb_ptr->d_agc_dl_ctrl = B_AGC_FULL_UPDATE; l1s.agc_dl_action = AGC_UPDATED; *state = WAIT_DSP_ACK; } else { // Enable the DSP AGC DL module l1s_dsp_com.dsp_ndb_ptr->d_agc_dl_ctrl = B_AGC_ENABLE; l1s.agc_dl_action = AGC_STARTED; *state = WAIT_DSP_ACK; } } if (l1a_l1s_com.agc_dl_task.parameters.agc_dl_control == AGC_STOP) { // AGC DL stop requested //------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_AGC_DL_STATE) { // Disable the DSP AGC DL module l1s_dsp_com.dsp_ndb_ptr->d_agc_dl_ctrl = B_AGC_DISABLE; l1s.agc_dl_action = AGC_STOPPED; *state = WAIT_DSP_ACK; } else { // AGC DL already disabled: confirm // Allocate confirmation message... l1s.agc_dl_action = AGC_NO_ACTION; conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_AGC_DL_CON; ((T_L1_AQI_AGC_DL_CON *)(conf_msg->SigP))->agc_dl_action = l1s.agc_dl_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.agc_dl_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_agc_dl_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_AGC_DL_CON; ((T_L1_AQI_AGC_DL_CON *)(conf_msg->SigP))->agc_dl_action = l1s.agc_dl_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_AGC_DL == 1 #if (L1_IIR == 2) /*-------------------------------------------------------*/ /* l1s_iir_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : IIR L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_iir_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_IIR_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.iir_task.parameters->iir_dl_control == IIR_START || l1a_l1s_com.iir_task.parameters->iir_dl_control == IIR_UPDATE ) { // IIR start or update requested //------------------------------ l1_audio_iir4x_copy_params(); if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_IIR_DL_STATE) { // IIR already started: update the DSP IIR module l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl = B_IIR_FULL_UPDATE; l1s.iir_dl_action = IIR_UPDATED; *state = WAIT_DSP_ACK; } else { // Enable the DSP IIR module l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl = B_IIR_ENABLE; l1s.iir_dl_action = IIR_STARTED; *state = WAIT_DSP_ACK; } } if (l1a_l1s_com.iir_task.parameters->iir_dl_control == IIR_STOP) { // IIR stop requested //------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_IIR_DL_STATE) { // Disable the DSP IIR module l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl = B_IIR_DISABLE; l1s.iir_dl_action = IIR_STOPPED; *state = WAIT_DSP_ACK; } else { // IIR already disabled: confirm // Allocate confirmation message... l1s.iir_dl_action = IIR_NO_ACTION; conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_IIR_DL_CON; ((T_L1_AQI_IIR_DL_CON *)(conf_msg->SigP))->iir_dl_action = l1s.iir_dl_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.iir_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_iir_dl_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_IIR_DL_CON; ((T_L1_AQI_IIR_DL_CON *)(conf_msg->SigP))->iir_dl_action = l1s.iir_dl_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_IIR == 2 #if (L1_WCM == 1) /*-------------------------------------------------------*/ /* l1s_wcm_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : WCM L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_wcm_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_WCM_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.wcm_task.parameters->wcm_control == WCM_START || l1a_l1s_com.wcm_task.parameters->wcm_control == WCM_UPDATE ) { UWORD8 i; // WCM start or update requested //------------------------------ l1s_dsp_com.dsp_ndb_ptr->d_wcm_mode = l1a_l1s_com.wcm_task.parameters->parameters.mode; l1s_dsp_com.dsp_ndb_ptr->d_wcm_frame_size = l1a_l1s_com.wcm_task.parameters->parameters.frame_size; l1s_dsp_com.dsp_ndb_ptr->d_wcm_num_sub_frames = l1a_l1s_com.wcm_task.parameters->parameters.num_sub_frames; l1s_dsp_com.dsp_ndb_ptr->d_wcm_ratio = l1a_l1s_com.wcm_task.parameters->parameters.ratio; l1s_dsp_com.dsp_ndb_ptr->d_wcm_threshold = l1a_l1s_com.wcm_task.parameters->parameters.threshold; for (i=0; i < (WCM_1X_GAIN_TABLE_LENGTH); i++) { l1s_dsp_com.dsp_ndb_ptr->a_wcm_gain[i] = l1a_l1s_com.wcm_task.parameters->parameters.gain[i]; } if (l1s_dsp_com.dsp_ndb_ptr->d_audio_apps_status & B_WCM_STATE) { // WCM already started: update the DSP WCM module l1s_dsp_com.dsp_ndb_ptr->d_audio_apps_ctrl = B_WCM_FULL_UPDATE; l1s.wcm_action = WCM_UPDATED; *state = WAIT_DSP_ACK; } else { // Enable the DSP WCM module l1s_dsp_com.dsp_ndb_ptr->d_audio_apps_ctrl = B_WCM_ENABLE; l1s.wcm_action = WCM_STARTED; *state = WAIT_DSP_ACK; } } if (l1a_l1s_com.wcm_task.parameters->wcm_control == WCM_STOP) { // WCM stop requested //------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_audio_apps_status & B_WCM_STATE) { // Disable the DSP WCM module l1s_dsp_com.dsp_ndb_ptr->d_audio_apps_ctrl = B_WCM_DISABLE; l1s.wcm_action = WCM_STOPPED; *state = WAIT_DSP_ACK; } else { // WCM already disabled: confirm // Allocate confirmation message... l1s.wcm_action = WCM_NO_ACTION; conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_WCM_CON; ((T_L1_AQI_WCM_CON *)(conf_msg->SigP))->wcm_action = l1s.wcm_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.wcm_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_audio_apps_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_WCM_CON; ((T_L1_AQI_WCM_CON *)(conf_msg->SigP))->wcm_action = l1s.wcm_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_WCM == 2 #if (L1_DRC == 1) /*-------------------------------------------------------*/ /* l1s_drc_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : DRC L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_drc_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_DRC_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.drc_task.parameters->drc_dl_control == DRC_START || l1a_l1s_com.drc_task.parameters->drc_dl_control == DRC_UPDATE) { // DRC start or update requested //------------------------------ l1_audio_drc1x_copy_params(); if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_DRC_DL_STATE) { // DRC already started: update the DSP DRC module l1s_dsp_com.dsp_ndb_ptr->d_drc_dl_ctrl = B_DRC_FULL_UPDATE; l1s.drc_dl_action = DRC_UPDATED; *state = WAIT_DSP_ACK; } else { // Enable the DSP DRC module l1s_dsp_com.dsp_ndb_ptr->d_drc_dl_ctrl = B_DRC_ENABLE; l1s.drc_dl_action = DRC_STARTED; *state = WAIT_DSP_ACK; } } if (l1a_l1s_com.drc_task.parameters->drc_dl_control == DRC_STOP) { // DRC stop requested //------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_DRC_DL_STATE) { // Disable the DSP DRC module l1s_dsp_com.dsp_ndb_ptr->d_drc_dl_ctrl = B_DRC_DISABLE; l1s.drc_dl_action = DRC_STOPPED; *state = WAIT_DSP_ACK; } else { // DRC already disabled: confirm // Allocate confirmation message... l1s.drc_dl_action = DRC_NO_ACTION; conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_DRC_CON; ((T_L1_AQI_DRC_CON *)(conf_msg->SigP))->drc_dl_action = l1s.drc_dl_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.drc_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_drc_dl_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_AQI_DRC_CON; ((T_L1_AQI_DRC_CON *)(conf_msg->SigP))->drc_dl_action = l1s.drc_dl_action; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_DRC == 1 #if (L1_LIMITER == 1) /*-------------------------------------------------------*/ /* l1s_limiter_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : LIMITER L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_limiter_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1, WAIT_PARTIAL_UPDATE = 2 }; UWORD8 *state = &l1s.audio_state[L1S_LIMITER_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { /* LIMITER update command */ /*------------------------*/ if (l1a_l1s_com.limiter_task.command.update) { if (l1a_l1s_com.limiter_task.parameters.limiter_enable) { UWORD8 i; // LIMITER start requested //------------------------ // Set LIMITER parameters l1s_dsp_com.dsp_ndb_ptr->d_lim_block_size = l1a_l1s_com.limiter_task.parameters.block_size; l1s_dsp_com.dsp_ndb_ptr->d_lim_slope_update_period = l1a_l1s_com.limiter_task.parameters.slope_update_period; l1s_dsp_com.dsp_ndb_ptr->d_lim_nb_fir_coefs = l1a_l1s_com.limiter_task.parameters.nb_fir_coefs; for (i=0; i < ((l1a_l1s_com.limiter_task.parameters.nb_fir_coefs - 1)>>1) + 1; i++) l1s_dsp_com.dsp_ndb_ptr->a_lim_filter_coefs[i] = l1a_l1s_com.limiter_task.parameters.filter_coefs[i]; l1s_dsp_com.dsp_ndb_ptr->d_lim_gain_fall_q15 = l1a_l1s_com.limiter_task.parameters.gain_fall; l1s_dsp_com.dsp_ndb_ptr->d_lim_gain_rise_q15 = l1a_l1s_com.limiter_task.parameters.gain_rise; // a_lim_mul_low/high computation and update l1_audio_lim_update_mul_low_high(); if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_LIM_STATE) { // LIMITER already started: update the DSP LIMITER module l1s_dsp_com.dsp_ndb_ptr->d_lim_dl_ctrl = B_LIM_FULL_UPDATE; *state = WAIT_DSP_ACK; } else { // Enable the DSP LIMITER module l1s_dsp_com.dsp_ndb_ptr->d_lim_dl_ctrl = B_LIM_ENABLE; *state = WAIT_DSP_ACK; } } else // LIMITER start requested { // LIMITER stop requested //----------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_LIM_STATE) { // Disable the DSP LIMITER module l1s_dsp_com.dsp_ndb_ptr->d_lim_dl_ctrl = B_LIM_DISABLE; *state = WAIT_DSP_ACK; } else { // LIMITER already disabled: confirm // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_LIMITER_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.limiter_task.command.update = FALSE; } // LIMITER update /* LIMITER partial update command */ /*--------------------------------*/ else if (l1a_l1s_com.limiter_task.command.partial_update) { // Only update if the module is enabled if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_LIM_STATE) { // a_lim_mul_low/high computation and update l1_audio_lim_update_mul_low_high(); // Partial update of the DSP LIMITER module l1s_dsp_com.dsp_ndb_ptr->d_lim_dl_ctrl = B_LIM_UPDATE; *state = WAIT_PARTIAL_UPDATE; } // Disable the partial update command l1a_l1s_com.limiter_task.command.partial_update = FALSE; } } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_lim_dl_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_LIMITER_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; case WAIT_PARTIAL_UPDATE: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_lim_dl_ctrl == 0) { *state = IDLE; } } break; } // switch } #endif // L1_LIMITER == 1 #if (L1_ES == 1) /*******************************************/ /* ES configuration tables */ /*******************************************/ #pragma DATA_SECTION(default_es_configs,".flashcnst"); const T_ES_CONFIG default_es_configs[7] = { // Behavior 1 { (B_ES_UL | B_ES_DL | B_ES_NSF), C_ES_GAIN_DL_OFF, C_ES_GAIN_UL_1_OFF, C_ES_GAIN_UL_2_OFF, C_ES_TCL_6DB, C_ES_TCL_0DB, C_ES_TCL_12DB, C_ES_TCL_6DB, C_ES_TCL_0DB, C_ES_TCL_LOUD, C_ES_SW_CNT, C_ES_DT_CNT, C_ES_HG_CNT_1, /* DL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_0DB, C_ES_ATT_LIN_3DB}, /* UL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_15DB, C_ES_ATT_LIN_0DB} } , // Behavior 1a { (B_ES_UL | B_ES_DL), C_ES_GAIN_DL_OFF, C_ES_GAIN_UL_1_OFF, C_ES_GAIN_UL_2_OFF, C_ES_TCL_6DB, C_ES_TCL_0DB, C_ES_TCL_12DB, C_ES_TCL_6DB, C_ES_TCL_0DB, C_ES_TCL_LOUD, C_ES_SW_CNT, C_ES_DT_CNT, C_ES_HG_CNT_1A, /* DL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_0DB, C_ES_ATT_LIN_3DB}, /* UL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_6DB, C_ES_ATT_LIN_0DB} } , // Behavior 2a { (B_ES_UL | B_ES_DL | B_ES_NSF), C_ES_GAIN_DL_OFF, C_ES_GAIN_UL_1_OFF, C_ES_GAIN_UL_2_OFF, C_ES_TCL_6DB, C_ES_TCL_0DB, C_ES_TCL_12DB, C_ES_TCL_6DB, C_ES_TCL_0DB, C_ES_TCL_LOUD, C_ES_SW_CNT, C_ES_DT_CNT, C_ES_HG_CNT_2A, /* DL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_5DB, C_ES_ATT_LIN_0DB, C_ES_ATT_LIN_5DB}, /* UL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_6DB, C_ES_ATT_LIN_24DB, C_ES_ATT_LIN_0DB} } , // Behavior 2b { (B_ES_UL | B_ES_DL | B_ES_CNG), C_ES_GAIN_DL_OFF, C_ES_GAIN_UL_1_OFF, C_ES_GAIN_UL_2_OFF, C_ES_TCL_6DB, C_ES_TCL_0DB, C_ES_TCL_10DB, C_ES_TCL_4DB, C_ES_TCL_0DB, C_ES_TCL_LOUD, C_ES_SW_CNT, C_ES_DT_CNT, C_ES_HG_CNT_2B, /* DL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_8DB, C_ES_ATT_LIN_0DB, C_ES_ATT_LIN_8DB}, /* UL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_9DB, C_ES_ATT_LIN_36DB, C_ES_ATT_LIN_0DB} } , // Behavior 2c { (B_ES_UL | B_ES_DL | B_ES_CNG), C_ES_GAIN_DL_OFF, C_ES_GAIN_UL_1_OFF, C_ES_GAIN_UL_2_OFF, C_ES_TCL_M6DB, C_ES_TCL_M23DB, C_ES_TCL_0DB, C_ES_TCL_M6DB, C_ES_TCL_M3DB, C_ES_TCL_LOUD, C_ES_SW_CNT, C_ES_DT_CNT, C_ES_HG_CNT_2C, /* DL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_10DB, C_ES_ATT_LIN_0DB, C_ES_ATT_LIN_10DB}, /* UL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_12DB, C_ES_ATT_LIN_48DB, C_ES_ATT_LIN_0DB} } , // Behavior 2c_idle { (B_ES_UL | B_ES_DL | B_ES_CNG), C_ES_GAIN_DL_OFF, C_ES_GAIN_UL_1_OFF, C_ES_GAIN_UL_2_OFF, C_ES_TCL_M6DB, C_ES_TCL_M23DB, C_ES_TCL_0DB, C_ES_TCL_M6DB, C_ES_TCL_M3DB, C_ES_TCL_LOUD, C_ES_SW_CNT, C_ES_DT_CNT, C_ES_HG_CNT_2C_IDLE, /* DL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_10DB, C_ES_ATT_LIN_0DB, C_ES_ATT_LIN_10DB}, /* UL attenuation */ {C_ES_ATT_LIN_12DB, C_ES_ATT_LIN_12DB, C_ES_ATT_LIN_48DB, C_ES_ATT_LIN_0DB} } , // Behavior 3 { (B_ES_UL | B_ES_DL | B_ES_CNG), C_ES_GAIN_DL_OFF, C_ES_GAIN_UL_1_OFF, C_ES_GAIN_UL_2_OFF, C_ES_TCL_B3_FE_LS, C_ES_TCL_B3_DT_LS, C_ES_TCL_B3_FE_NS, C_ES_TCL_B3_DT_NS, C_ES_TCL_B3_NE, C_ES_TCL_LOUD, C_ES_SW_CNT, C_ES_DT_CNT, C_ES_HG_CNT_3, /* DL attenuation */ {C_ES_ATT_LIN_3DB, C_ES_ATT_LIN_16DB, C_ES_ATT_LIN_0DB, C_ES_ATT_LIN_21DB}, /* UL attenuation */ {C_ES_ATT_LIN_19DB, C_ES_ATT_LIN_19DB, C_ES_ATT_LIN_66DB, C_ES_ATT_LIN_0DB} } }; /*-------------------------------------------------------*/ /* l1s_es_manager() */ /*-------------------------------------------------------*/ /* */ /* Parameters : */ /* */ /* Return : */ /* */ /* Description : ES L1S manager task. */ /* */ /*-------------------------------------------------------*/ void l1s_es_manager(void) { enum states { IDLE = 0, WAIT_DSP_ACK = 1 }; UWORD8 *state = &l1s.audio_state[L1S_ES_STATE]; xSignalHeaderRec *conf_msg; switch(*state) { case IDLE: { if (l1a_l1s_com.es_task.parameters.es_enable) { const T_ES_CONFIG *es_cfg; // ES start requested //-------------------- // Set ES parameters if (l1a_l1s_com.es_task.parameters.es_behavior == ES_CUSTOM_PARAM) { es_cfg = &(l1a_l1s_com.es_task.parameters.es_config); } else { es_cfg = &(default_es_configs[l1a_l1s_com.es_task.parameters.es_behavior]); } // Set parameters in the API l1s_dsp_com.dsp_ndb_ptr->d_es_mode = es_cfg->es_mode; l1s_dsp_com.dsp_ndb_ptr->d_es_gain_dl = es_cfg->es_gain_dl; l1s_dsp_com.dsp_ndb_ptr->d_es_gain_ul_1 = es_cfg->es_gain_ul_1; l1s_dsp_com.dsp_ndb_ptr->d_es_gain_ul_2 = es_cfg->es_gain_ul_2; l1s_dsp_com.dsp_ndb_ptr->d_es_tcl_fe_ls_thr = es_cfg->tcl_fe_ls_thr; l1s_dsp_com.dsp_ndb_ptr->d_es_tcl_dt_ls_thr = es_cfg->tcl_dt_ls_thr; l1s_dsp_com.dsp_ndb_ptr->d_es_tcl_fe_ns_thr = es_cfg->tcl_fe_ns_thr; l1s_dsp_com.dsp_ndb_ptr->d_es_tcl_dt_ns_thr = es_cfg->tcl_dt_ns_thr; l1s_dsp_com.dsp_ndb_ptr->d_es_tcl_ne_thr = es_cfg->tcl_ne_thr; l1s_dsp_com.dsp_ndb_ptr->d_es_ref_ls_pwr = es_cfg->ref_ls_pwr; l1s_dsp_com.dsp_ndb_ptr->d_es_switching_time = es_cfg->switching_time; l1s_dsp_com.dsp_ndb_ptr->d_es_switching_time_dt = es_cfg->switching_time_dt; l1s_dsp_com.dsp_ndb_ptr->d_es_hang_time = es_cfg->hang_time; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_dl_vect[0] = es_cfg->gain_lin_dl_vect[0]; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_dl_vect[1] = es_cfg->gain_lin_dl_vect[1]; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_dl_vect[2] = es_cfg->gain_lin_dl_vect[2]; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_dl_vect[3] = es_cfg->gain_lin_dl_vect[3]; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_ul_vect[0] = es_cfg->gain_lin_ul_vect[0]; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_ul_vect[1] = es_cfg->gain_lin_ul_vect[1]; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_ul_vect[2] = es_cfg->gain_lin_ul_vect[2]; l1s_dsp_com.dsp_ndb_ptr->a_es_gain_lin_ul_vect[3] = es_cfg->gain_lin_ul_vect[3]; if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ES_STATE) { // ES already started: update the DSP ES module l1s_dsp_com.dsp_ndb_ptr->d_es_ctrl = B_ES_FULL_UPDATE; *state = WAIT_DSP_ACK; } else { // Enable the DSP ES module l1s_dsp_com.dsp_ndb_ptr->d_es_ctrl = B_ES_ENABLE; *state = WAIT_DSP_ACK; } } else // ES start requested { // ES stop requested //------------------- if (l1s_dsp_com.dsp_ndb_ptr->d_aqi_status & B_ES_STATE) { // Disable the DSP ES module l1s_dsp_com.dsp_ndb_ptr->d_es_ctrl = B_ES_DISABLE; *state = WAIT_DSP_ACK; } else { // ES already disabled: confirm // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_ES_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } } // Disable the update command l1a_l1s_com.es_task.command.update = FALSE; } break; case WAIT_DSP_ACK: { // The DSP acknowledged the L1S command if (l1s_dsp_com.dsp_ndb_ptr->d_es_ctrl == 0) { // Allocate confirmation message... conf_msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) conf_msg->SignalCode = L1_ES_CON; // Send confirmation message... os_send_sig(conf_msg, L1C1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) *state = IDLE; } } break; } // switch } #endif // L1_ES == 1 #endif // AUDIO_TASK