FreeCalypso > hg > fc-magnetite
view src/cs/layer1/audio_cfile/l1audio_sync.c @ 677:91d9f8506420
GPIO046 dummy outputs on FCDEV3B, GTA0x and Tango
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 20 Jun 2020 04:32:45 +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