view src/cs/layer1/audio_cfile/l1audio_sync.c @ 688:5806383e2788

doc/Compiling: update for luna1, luna2 and tangomdm
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 12 Oct 2020 19:17:23 +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