/****************************************************************************/
/*                                                                          */
/*  File Name:  audio_api.c                                                 */
/*                                                                          */
/*  Purpose:  This file contains all the functions used to service          */
/*            primitives.                                                   */
/*                                                                          */
/*  Version   0.1                                                           */
/*                                                                          */
/*  Date        Modification                                                */
/*  ------------------------------------------------------------------------*/
/*  14 May 2001  Create                                                     */
/*                                                                          */
/*  Author      Francois Mazard - Stephanie Gerthoux                        */
/*                                                                          */
/* (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved*/
/****************************************************************************/

#include "rv/rv_defined_swe.h"

#ifdef RVM_AUDIO_MAIN_SWE
  #ifndef _WINDOWS
    #include "config/swconfig.cfg"
	#include "config/sys.cfg"
	#include "config/chipset.cfg"
  #endif

  #include "l1_confg.h"
  #include "l1audio_cust.h"
  #include "rv/rv_general.h"
  #include "rvm/rvm_gen.h"
  #include "audio/audio_ffs_i.h"
  #include "audio/audio_api.h"
  #include "audio/audio_structs_i.h"
  #include "audio/audio_error_hdlr_i.h"
  #include "audio/audio_var_i.h"
  #include "audio/audio_messages_i.h"
  #include "rvf/rvf_target.h"
  #include "audio/audio_const_i.h"
  #include "audio/audio_macro_i.h"
  #include "ffs/ffs_api.h"

#include <string.h>

  /* external dependency */
  #if (SPEECH_RECO)
    extern INT8 audio_sr_create_vocabulary_database(char* directory, void** pp_database);
  #endif
  /* read */
  extern T_AUDIO_RET audio_mode_voice_path_read               (T_AUDIO_VOICE_PATH_SETTING *data);
  extern T_AUDIO_RET audio_mode_microphone_mode_read          (INT8  *data);
  extern T_AUDIO_RET audio_mode_microphone_gain_read          (INT8  *data);
  extern T_AUDIO_RET audio_mode_microphone_extra_gain_read    (INT8  *data);
  extern T_AUDIO_RET audio_mode_microphone_output_bias_read   (INT8  *data);
  extern T_AUDIO_RET audio_mode_microphone_fir_read           (T_AUDIO_FIR_COEF *data);
  extern T_AUDIO_RET audio_mode_speaker_mode_read             (INT8  *data);
  extern T_AUDIO_RET audio_mode_speaker_gain_read             (INT8  *data);
  extern T_AUDIO_RET audio_mode_speaker_filter_read           (INT8  *data);
  extern T_AUDIO_RET audio_mode_speaker_fir_read              (T_AUDIO_FIR_COEF *data);
  extern T_AUDIO_RET audio_mode_speaker_buzzer_read           (INT8  *data);
  extern T_AUDIO_RET audio_mode_sidetone_gain_read            (INT8  *data);
  extern T_AUDIO_RET audio_mode_aec_read                      (T_AUDIO_AEC_CFG *data);
  extern T_AUDIO_RET audio_mode_speaker_volume_read           (T_AUDIO_SPEAKER_LEVEL *data);

  T_AUDIO_RET audio_driver_handle_session(UINT32 msg_id, UINT8 channel_id, T_RV_RETURN return_path);


  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_keybeep_start                                      */
  /*                                                                              */
  /*    Purpose:  This function is called to initiate a key beep generation       */
  /*              and DTMF generation. The key beep is the generation of two      */
  /*              sine waves                                                      */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio Key Beep Parameters,                                            */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the keybeep parameters.                                */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_keybeep_start (T_AUDIO_KEYBEEP_PARAMETER parameter,
                                    T_RV_RETURN return_path)
  {
    #if (KEYBEEP)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS   mb_status = RVF_GREEN;
      T_AUDIO_KEYBEEP_START *p_msg_start = NULL;

      /************************ audio_keybeep_start function begins ******************/

      if (p_audio_gbl_var == NULL )
      {
         audio_keybeep_error_trace(AUDIO_ENTITY_NOT_START);
         return(AUDIO_ERROR);
      }

      /* If bad parameters, then report an error and abort.*/
      if ((parameter.frequency_beep[0] < FREQUENCY_BEEP_MIN) ||
          (parameter.frequency_beep[0] > FREQUENCY_BEEP_MAX) ||
          (parameter.frequency_beep[1] < FREQUENCY_BEEP_MIN) ||
          (parameter.frequency_beep[1] > FREQUENCY_BEEP_MAX) ||
          (parameter.amplitude_beep[0] < AMPLITUDE_BEEP_MIN) ||
          (parameter.amplitude_beep[0] > AMPLITUDE_BEEP_MAX) ||
          (parameter.amplitude_beep[1] < AMPLITUDE_BEEP_MIN) ||
          (parameter.amplitude_beep[1] > AMPLITUDE_BEEP_MAX) ||
          (parameter.duration < DURATION_BEEP_MIN ))
      {
        audio_keybeep_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_KEYBEEP_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.     */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_keybeep_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_keybeep_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_KEYBEEP_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->keybeep_parameter.frequency_beep[0]     = parameter.frequency_beep[0];
      p_msg_start->keybeep_parameter.frequency_beep[1]     = parameter.frequency_beep[1];
      p_msg_start->keybeep_parameter.amplitude_beep[0]     = parameter.amplitude_beep[0];
      p_msg_start->keybeep_parameter.amplitude_beep[1]     = parameter.amplitude_beep[1];
      p_msg_start->keybeep_parameter.duration              = parameter.duration;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
       else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Keybeep not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_Keybeep_Start function ******************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_keybeep_stop                                       */
  /*                                                                              */
  /*    Purpose:  This function is called to stop a key beep generation           */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_keybeep_stop (T_RV_RETURN return_path)
  {
    #if (KEYBEEP)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS   mb_status = RVF_GREEN;
      T_AUDIO_KEYBEEP_STOP *p_msg  = NULL;

      /************************ audio_keybeep_stop function begins ****************/

      if (p_audio_gbl_var == NULL )
      {
        audio_keybeep_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_KEYBEEP_STOP),
                               (T_RVF_BUFFER **) (&p_msg));

      /* If insufficient resources, then report a memory error and abort.         */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg);
        audio_keybeep_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_keybeep_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }


      /* fill the message id */
      p_msg->os_hdr.msg_id = AUDIO_KEYBEEP_STOP_REQ;

      /* fill the address source id */
      p_msg->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      if (return_path.callback_func == NULL)
      {
        p_msg->return_path.addr_id = return_path.addr_id;
        p_msg->return_path.callback_func = NULL;
      }
       else
      {
        p_msg->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Keybeep not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_Keybeep_Stop function *******************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_tones_start                                        */
  /*                                                                              */
  /*    Purpose:  This function is called to initiate tones generation.           */
  /*              The tones are the generation of up to three scheduled           */
  /*              sine waves..........................................            */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio tones Parameters,                                               */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the tones parameters.                                  */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_tones_start (T_AUDIO_TONES_PARAMETER* parameter,
                                 T_RV_RETURN return_path)
  {
    #if (TONE)
      /* Declare local variables. */
      T_RVF_MB_STATUS   mb_status = RVF_GREEN;
      T_AUDIO_TONES_START *p_msg_start = NULL;

    /************************ audio_tones_start function begins ********************/

      if (p_audio_gbl_var == NULL )
      {
        audio_tones_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* If bad tones parameters, then report an error and abort.*/
      if ( (parameter->tones[0].frequency_tone < FREQUENCY_BEEP_MIN) ||
           (parameter->tones[1].frequency_tone < FREQUENCY_BEEP_MIN) ||
           (parameter->tones[2].frequency_tone < FREQUENCY_BEEP_MIN) ||
           (parameter->tones[0].frequency_tone > FREQUENCY_BEEP_MAX) ||
           (parameter->tones[1].frequency_tone > FREQUENCY_BEEP_MAX) ||
           (parameter->tones[2].frequency_tone > FREQUENCY_BEEP_MAX) ||
           (parameter->tones[0].amplitude_tone < AMPLITUDE_BEEP_MIN) ||
           (parameter->tones[1].amplitude_tone < AMPLITUDE_BEEP_MIN) ||
           (parameter->tones[2].amplitude_tone < AMPLITUDE_BEEP_MIN) ||
           (parameter->tones[0].amplitude_tone > AMPLITUDE_BEEP_MAX) ||
           (parameter->tones[1].amplitude_tone > AMPLITUDE_BEEP_MAX) ||
           (parameter->tones[2].amplitude_tone > AMPLITUDE_BEEP_MAX) ||
           (parameter->frame_duration == 0 )                         ||
           (parameter->period_duration < parameter->sequence_duration) ||
           (parameter->sequence_duration < parameter->frame_duration)  ||
           (parameter->period_duration < parameter->frame_duration)    ||
           ((parameter->tones[0].stop_tone - parameter->tones[0].start_tone) < DURATION_BEEP_MIN) ||
           ((parameter->tones[1].stop_tone - parameter->tones[1].start_tone) < DURATION_BEEP_MIN) ||
           ((parameter->tones[2].stop_tone - parameter->tones[2].start_tone) < DURATION_BEEP_MIN) )
      {
        audio_tones_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_TONES_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.     */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_tones_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_tones_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_TONES_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->tones_parameter.tones[0].frequency_tone = parameter->tones[0].frequency_tone;
      p_msg_start->tones_parameter.tones[1].frequency_tone = parameter->tones[1].frequency_tone;
      p_msg_start->tones_parameter.tones[2].frequency_tone = parameter->tones[2].frequency_tone;

      p_msg_start->tones_parameter.tones[0].amplitude_tone = parameter->tones[0].amplitude_tone;
      p_msg_start->tones_parameter.tones[1].amplitude_tone = parameter->tones[1].amplitude_tone;
      p_msg_start->tones_parameter.tones[2].amplitude_tone = parameter->tones[2].amplitude_tone;

      p_msg_start->tones_parameter.tones[0].start_tone = parameter->tones[0].start_tone;
      p_msg_start->tones_parameter.tones[1].start_tone = parameter->tones[1].start_tone;
      p_msg_start->tones_parameter.tones[2].start_tone = parameter->tones[2].start_tone;
      p_msg_start->tones_parameter.tones[0].stop_tone = parameter->tones[0].stop_tone;
      p_msg_start->tones_parameter.tones[1].stop_tone = parameter->tones[1].stop_tone;
      p_msg_start->tones_parameter.tones[2].stop_tone = parameter->tones[2].stop_tone;

      p_msg_start->tones_parameter.frame_duration= parameter->frame_duration;
      p_msg_start->tones_parameter.sequence_duration = parameter->sequence_duration;
      p_msg_start->tones_parameter.period_duration = parameter->period_duration;
      p_msg_start->tones_parameter.repetition = parameter->repetition;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
       else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Tones not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_tones_Start function ********************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_tones_stop                                         */
  /*                                                                              */
  /*    Purpose:  This function is called to stop a tones generation              */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        Validation of the tones parameters.                                   */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_tones_stop (T_RV_RETURN return_path)
  {
    #if (TONE)
      /* Declare local variables.                                                  */
      T_RVF_MB_STATUS   mb_status = RVF_GREEN;
      T_AUDIO_TONES_STOP *p_msg  = NULL;

    /************************ audio_tones_stop function begins *********************/

      if (p_audio_gbl_var == NULL )
      {
        audio_tones_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_TONES_STOP),
                               (T_RVF_BUFFER **) (&p_msg));

      /* If insufficient resources, then report a memory error and abort.           */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg);
        audio_tones_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_tones_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg->os_hdr.msg_id = AUDIO_TONES_STOP_REQ;

      /* fill the address source id */
      p_msg->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      if (return_path.callback_func == NULL)
      {
        p_msg->return_path.addr_id = return_path.addr_id;
        p_msg->return_path.callback_func = NULL;
      }
       else
      {
        p_msg->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Tones not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_Tones_Stop function *********************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_melody_E1_start                                    */
  /*                                                                              */
  /*    Purpose:  This function is called to initiate the melody E1 generation    */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio Melody E1 Parameters,                                           */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the melody E1 parameters.                              */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_melody_E1_start (T_AUDIO_MELODY_E1_PARAMETER *p_parameter,
                                     T_RV_RETURN return_path)
  {
    #if (MELODY_E1)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS   mb_status = RVF_GREEN;
      T_AUDIO_MELODY_E1_START *p_msg_start = NULL;
      T_FFS_FD            ffs_fd;

    /************************ audio_melody_E1_start function begins ***************/

      if (p_audio_gbl_var == NULL )
      {
        audio_melody_E1_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the melody E1 file exist */
      #ifndef _WINDOWS
        ffs_fd = ffs_open(p_parameter->melody_name, FFS_O_RDONLY);
        if (ffs_fd <= 0)
        {
          audio_melody_E1_error_trace(AUDIO_ENTITY_FILE_ERROR);
          return (AUDIO_ERROR);
        }
      #else
        ffs_fd = 0x00000001;
      #endif

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_MELODY_E1_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.               */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_melody_E1_error_trace(AUDIO_ENTITY_NO_MEMORY);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_melody_E1_error_trace(AUDIO_ENTITY_NO_MEMORY);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_MELODY_E1_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->audio_ffs_fd = ffs_fd;

      strcpy(p_msg_start->melody_E1_parameter.melody_name,
        p_parameter->melody_name);

      if ( (p_parameter->loopback == AUDIO_MELODY_NO_LOOPBACK) ||
           (p_parameter->loopback == AUDIO_MELODY_LOOPBACK) )
      {
        p_msg_start->melody_E1_parameter.loopback = p_parameter->loopback;
      }
      else
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        /* Wrong parameter */
        audio_melody_E1_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      if ( (p_parameter->melody_mode == AUDIO_MELODY_GAME_MODE) ||
           (p_parameter->melody_mode == AUDIO_MELODY_NORMAL_MODE) )
      {
        p_msg_start->melody_E1_parameter.melody_mode     = p_parameter->melody_mode;
      }
      else
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        /* Wrong parameter */
        audio_melody_E1_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }

      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Melody E1 not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_melody_E1_Start function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_melody_E1_stop                                     */
  /*                                                                              */
  /*    Purpose:  This function is called to stop a melody_E1 generation          */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio Melody E1 Stop Parameters,                                      */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the melody E1 parameters.                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_melody_E1_stop (T_AUDIO_MELODY_E1_STOP_PARAMETER *p_parameter,
                                    T_RV_RETURN return_path)
  {
    #if (MELODY_E1)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS   mb_status = RVF_GREEN;
      T_AUDIO_MELODY_E1_STOP *p_msg  = NULL;

    /************************ audio_melody_E1_stop function begins ****************/

      if (p_audio_gbl_var == NULL )
      {
        audio_melody_E1_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_MELODY_E1_STOP),
                               (T_RVF_BUFFER **) (&p_msg));

      /* If insufficient resources, then report a memory error and abort.        */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg);
        audio_melody_E1_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_melody_E1_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg->os_hdr.msg_id = AUDIO_MELODY_E1_STOP_REQ;

      /* fill the address source id */
      p_msg->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      strcpy (p_msg->melody_name, p_parameter->melody_name);

      if (return_path.callback_func == NULL)
      {
        p_msg->return_path.addr_id = return_path.addr_id;
        p_msg->return_path.callback_func = NULL;
      }
       else
      {
        p_msg->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Melody E1 not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_melody_E1_Stop function *****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_vm_play_start                                      */
  /*                                                                              */
  /*    Purpose:  This function is called to initiate the voice Memorization play */
  /*              generation                                                      */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio Voice Memorization Play Parameters,                             */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the Voice Memorization Play parameters.                */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_vm_play_start (T_AUDIO_VM_PLAY_PARAMETER *p_parameter,
                                   T_RV_RETURN return_path)
  {
    #if (VOICE_MEMO)
      /* Declare local variables. */
      T_RVF_MB_STATUS       mb_status = RVF_GREEN;
      T_AUDIO_VM_PLAY_START *p_msg_start = NULL;
      T_FFS_FD            ffs_fd;

    /************************ audio_vm_play_start function begins ******************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the voice memo play file exist        */
      #ifndef _WINDOWS
        ffs_fd = ffs_open(p_parameter->memo_name, FFS_O_RDONLY);
        if ( ffs_fd <= 0)
        {
          audio_voice_memo_error_trace(AUDIO_ENTITY_FILE_ERROR);
          return (AUDIO_ERROR);
        }
      #else
        ffs_fd = 0x00000010;
      #endif

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_PLAY_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.        */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_PLAY_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->audio_ffs_fd = ffs_fd;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }

      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("VM Play not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_vm_play_start function ******************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_vm_play_stop                                       */
  /*                                                                              */
  /*    Purpose:  This function is called to stop a voice memorization Play       */
  /*              generation                                                      */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_vm_play_stop (T_RV_RETURN return_path)
  {
    #if (VOICE_MEMO)
      /* Declare local variables.                                                  */
      T_RVF_MB_STATUS        mb_status = RVF_GREEN;
      T_AUDIO_VM_PLAY_STOP   *p_msg  = NULL;

    /************************ audio_vm_play_stop function begins *******************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_PLAY_STOP),
                               (T_RVF_BUFFER **) (&p_msg));

      /* If insufficient resources, then report a memory error and abort.            */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg);
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg->os_hdr.msg_id = AUDIO_VM_PLAY_STOP_REQ;

      /* fill the address source id */
      p_msg->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      if (return_path.callback_func == NULL)
      {
        p_msg->return_path.addr_id = return_path.addr_id;
        p_msg->return_path.callback_func = NULL;
      }
       else
      {
        p_msg->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("VM Play not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_vm_play_Stop function *******************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_vm_record_start                                    */
  /*                                                                              */
  /*    Purpose:  This function is called to initiate the voice Memorization      */
  /*              record generation                                               */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio Voice Memorization Record Parameters,                           */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the Voice Memorization Record parameters.              */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_vm_record_start ( T_AUDIO_VM_RECORD_PARAMETER *p_record_parameter,
                                      T_AUDIO_TONES_PARAMETER *p_tones_parameter,
                                      T_RV_RETURN return_path)
  {
    #if (VOICE_MEMO)
      /* Declare local variables. */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_VM_RECORD_START   *p_msg_start = NULL;
      T_FFS_FD            ffs_fd;

      /************************ audio_vm_record_start function begins **************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the voice memo record file already exist        */
      #ifndef _WINDOWS
        ffs_fd = ffs_open(p_record_parameter->memo_name,
                  FFS_O_CREATE | FFS_O_WRONLY | FFS_O_TRUNC | FFS_O_APPEND);
        if ( ffs_fd <= 0)
        {
          audio_voice_memo_error_trace(AUDIO_ENTITY_FILE_ERROR);
          return (AUDIO_ERROR);
        }
      #else
        ffs_fd = 0x00000011;
      #endif

      /* If bad tones parameters, then report an error and abort.*/
      if ( (p_tones_parameter->tones[0].frequency_tone < FREQUENCY_BEEP_MIN) ||
           (p_tones_parameter->tones[1].frequency_tone < FREQUENCY_BEEP_MIN) ||
           (p_tones_parameter->tones[2].frequency_tone < FREQUENCY_BEEP_MIN) ||
           (p_tones_parameter->tones[0].frequency_tone > FREQUENCY_BEEP_MAX) ||
           (p_tones_parameter->tones[1].frequency_tone > FREQUENCY_BEEP_MAX) ||
           (p_tones_parameter->tones[2].frequency_tone > FREQUENCY_BEEP_MAX) ||
           (p_tones_parameter->tones[0].amplitude_tone < AMPLITUDE_BEEP_MIN) ||
           (p_tones_parameter->tones[1].amplitude_tone < AMPLITUDE_BEEP_MIN) ||
           (p_tones_parameter->tones[2].amplitude_tone < AMPLITUDE_BEEP_MIN) ||
           (p_tones_parameter->tones[0].amplitude_tone > AMPLITUDE_BEEP_MAX) ||
           (p_tones_parameter->tones[1].amplitude_tone > AMPLITUDE_BEEP_MAX) ||
           (p_tones_parameter->tones[2].amplitude_tone > AMPLITUDE_BEEP_MAX) ||
           (p_tones_parameter->frame_duration == 0 )                         ||
           (p_tones_parameter->period_duration < p_tones_parameter->sequence_duration) ||
           (p_tones_parameter->sequence_duration < p_tones_parameter->frame_duration)  ||
           (p_tones_parameter->period_duration < p_tones_parameter->frame_duration)    ||
           ((p_tones_parameter->tones[0].stop_tone - p_tones_parameter->tones[0].start_tone) < DURATION_BEEP_MIN) ||
           ((p_tones_parameter->tones[1].stop_tone - p_tones_parameter->tones[1].start_tone) < DURATION_BEEP_MIN) ||
           ((p_tones_parameter->tones[2].stop_tone - p_tones_parameter->tones[2].start_tone) < DURATION_BEEP_MIN) )
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        #ifndef _WINDOWS
          /* close the file previously open */
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      /* If bad voice memo record parameters, then report an error and abort.*/
      if ( ( p_record_parameter->memo_duration == 0) ||
           (( p_record_parameter->compression_mode != AUDIO_VM_NO_COMPRESSION_MODE ) &&
            ( p_record_parameter->compression_mode != AUDIO_VM_COMPRESSION_MODE )))
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        #ifndef _WINDOWS
          /* close the file previously open */
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_RECORD_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        #ifndef _WINDOWS
          /* close the file previously open */
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        #ifndef _WINDOWS
          /* close the file previously open */
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_RECORD_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->audio_ffs_fd                           = ffs_fd;
      p_msg_start->compression_mode   = p_record_parameter->compression_mode;
      p_msg_start->memo_duration      = p_record_parameter->memo_duration;
      p_msg_start->microphone_gain    = p_record_parameter->microphone_gain;
      p_msg_start->network_gain       = p_record_parameter->network_gain;

      /* fill the message tones parameters */
      p_msg_start->tones_parameter.tones[0].frequency_tone = p_tones_parameter->tones[0].frequency_tone;
      p_msg_start->tones_parameter.tones[1].frequency_tone = p_tones_parameter->tones[1].frequency_tone;
      p_msg_start->tones_parameter.tones[2].frequency_tone = p_tones_parameter->tones[2].frequency_tone;

      p_msg_start->tones_parameter.tones[0].amplitude_tone = p_tones_parameter->tones[0].amplitude_tone;
      p_msg_start->tones_parameter.tones[1].amplitude_tone = p_tones_parameter->tones[1].amplitude_tone;
      p_msg_start->tones_parameter.tones[2].amplitude_tone = p_tones_parameter->tones[2].amplitude_tone;

      p_msg_start->tones_parameter.tones[0].start_tone = p_tones_parameter->tones[0].start_tone;
      p_msg_start->tones_parameter.tones[1].start_tone = p_tones_parameter->tones[1].start_tone;
      p_msg_start->tones_parameter.tones[2].start_tone = p_tones_parameter->tones[2].start_tone;
      p_msg_start->tones_parameter.tones[0].stop_tone = p_tones_parameter->tones[0].stop_tone;
      p_msg_start->tones_parameter.tones[1].stop_tone = p_tones_parameter->tones[1].stop_tone;
      p_msg_start->tones_parameter.tones[2].stop_tone = p_tones_parameter->tones[2].stop_tone;

      p_msg_start->tones_parameter.frame_duration= p_tones_parameter->frame_duration;
      p_msg_start->tones_parameter.sequence_duration = p_tones_parameter->sequence_duration;
      p_msg_start->tones_parameter.period_duration = p_tones_parameter->period_duration;
      p_msg_start->tones_parameter.repetition = p_tones_parameter->repetition;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }

      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("VM Record not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_vm_record_start function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_vm_record_stop                                     */
  /*                                                                              */
  /*    Purpose:  This function is called to stop a voice memorization Record     */
  /*              generation                                                      */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_vm_record_stop (T_RV_RETURN return_path)
  {
    #if (VOICE_MEMO)
      /* Declare local variables.                                                  */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_VM_RECORD_STOP    *p_msg  = NULL;

    /************************ audio_vm_record_stop function begins *****************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_RECORD_STOP),
                               (T_RVF_BUFFER **) (&p_msg));

      /* If insufficient resources, then report a memory error and abort.          */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg);
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_voice_memo_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg->os_hdr.msg_id = AUDIO_VM_RECORD_STOP_REQ;

      /* fill the address source id */
      p_msg->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      if (return_path.callback_func == NULL)
      {
        p_msg->return_path.addr_id = return_path.addr_id;
        p_msg->return_path.callback_func = NULL;
      }
       else
      {
        p_msg->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("VM Record not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_vm_record_Stop function *****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_sr_enroll_start                                    */
  /*                                                                              */
  /*    Purpose:  This function is called to start the SR enrollment              */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        SR enrollment parameters                                              */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_sr_enroll_start (T_AUDIO_SR_ENROLL_PARAMETER *p_parameter,
                                     T_RV_RETURN return_path)
  {
    #if (SPEECH_RECO)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_SR_ENROLL_START   *p_msg_start  = NULL;
      char                      sr_name[AUDIO_SR_PATH_NAME_MAX_SIZE];
      T_FFS_FD            ffs_fd, sr_ffs_fd;

    /************************ audio_sr_enroll_start function begins ***************/

      if (p_audio_gbl_var == NULL )
      {
        audio_sr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* Check the speech sample parameter */
      if ( (p_parameter->record_speech != AUDIO_SR_RECORD_SPEECH)     &&
           (p_parameter->record_speech != AUDIO_SR_NO_RECORD_SPEECH) )
      {
        audio_sr_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        return(AUDIO_ERROR);
      }

      /* Create the speech recognition sample file name */
      strcpy(sr_name, p_parameter->enroll_name);
      strcat(sr_name,"_sr");

      #ifndef _WINDOWS
        sr_ffs_fd = ffs_open(sr_name,
          FFS_O_CREATE | FFS_O_WRONLY | FFS_O_TRUNC | FFS_O_APPEND);
        if (sr_ffs_fd <= 0)
        {
          audio_sr_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return(AUDIO_ERROR);
      }
      #else
        sr_ffs_fd = 0x00000100;
      #endif

      /* Create the speech sample file if it's requested.*/
      if (p_parameter->record_speech == AUDIO_SR_RECORD_SPEECH)
      {
      #ifndef _WINDOWS
          ffs_fd = ffs_open(p_parameter->enroll_name,
                      FFS_O_CREATE | FFS_O_WRONLY | FFS_O_TRUNC | FFS_O_APPEND);
        if (ffs_fd <= 0)
        {
            ffs_close(sr_ffs_fd);
            audio_sr_error_trace(AUDIO_ENTITY_FILE_ERROR);
          return (AUDIO_ERROR);
        }
      #else
          ffs_fd = 0x00000101;
      #endif
      }
      else
      {
        ffs_fd = AUDIO_SR_NO_RECORD_SPEECH;
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_SR_ENROLL_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.               */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        #ifndef _WINDOWS
          /* close the file previously open */
          ffs_close(sr_ffs_fd);
          if (p_parameter->record_speech == AUDIO_SR_RECORD_SPEECH)
          {
            ffs_close(ffs_fd);
          }
        #endif
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        #ifndef _WINDOWS
          /* close the file previously open */
          ffs_close(sr_ffs_fd);
          if (p_parameter->record_speech == AUDIO_SR_RECORD_SPEECH)
          {
            ffs_close(ffs_fd);
          }
        #endif
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_SR_ENROLL_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->sr_ffs_fd = sr_ffs_fd;
      p_msg_start->voice_ffs_fd = ffs_fd;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Speech Reco not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_enroll_Start function **********************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_sr_enroll_stop                                     */
  /*                                                                              */
  /*    Purpose:  This function is called to stop the SR enrollment               */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        SR enrollment parameters                                              */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_sr_enroll_stop (T_RV_RETURN return_path)
  {
    #if (SPEECH_RECO)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_SR_ENROLL_STOP   *p_msg_start  = NULL;

    /************************ audio_sr_enroll_start function begins ***************/

      if (p_audio_gbl_var == NULL )
      {
        audio_sr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_SR_ENROLL_STOP),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.          */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_SR_ENROLL_STOP_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Speech Reco not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_sr_enroll_stop function *****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_sr_update_start                                    */
  /*                                                                              */
  /*    Purpose:  This function is called to start the SR update                  */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        SR update parameters                                                  */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_sr_update_start (T_AUDIO_SR_UPDATE_PARAMETER *p_parameter,
                                     T_RV_RETURN return_path)
  {
    #if (SPEECH_RECO)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_SR_UPDATE_START  *p_msg_start  = NULL;
      UINT8                     i, folder_size=0, path_size;
      char                      sr_name[AUDIO_SR_PATH_NAME_MAX_SIZE],
                                sr_dir[AUDIO_SR_PATH_NAME_MAX_SIZE],
                                *p_database;
      INT8                      model_index, model_number;
      #ifndef _WINDOWS
        char                    *p_model_path;
      #endif

    /************************ audio_sr_update_start function begins ***************/

      if (p_audio_gbl_var == NULL )
      {
        audio_sr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* Check the speech sample parameter */
      if ( (p_parameter->record_speech != AUDIO_SR_RECORD_SPEECH)     &&
           (p_parameter->record_speech != AUDIO_SR_NO_RECORD_SPEECH) )
      {
        audio_sr_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        return(AUDIO_ERROR);
      }

      /* Create the speech recognition sample file name */
      strcpy(sr_name, p_parameter->update_name);
      strcat(sr_name,"_sr");

      /* Check the number of speech reco model are included in the current folder */
      /* in order to know if the update or the update check needs to be run */
      path_size = (UINT8)strlen(p_parameter->update_name);
      i = 0;
      while (i < path_size)
      {
        if (strncmp(&(p_parameter->update_name[i]), "/", 1) == 0)
        {
          folder_size = i;
        }
        i++;
      }
      if ((folder_size + 1) == path_size)
      {
      /* this isn't a name but a folder */
      audio_sr_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
      return(AUDIO_ERROR);
      }
      /* Create the speech recognition folder name */
      strncpy(sr_dir, p_parameter->update_name, folder_size);
      sr_dir[folder_size] = 0;

      /* check the number of model in the database */
      model_number = audio_sr_create_vocabulary_database(sr_dir, (void **)(&p_database));
      if (model_number == AUDIO_ERROR)
      {
        return(AUDIO_ERROR);
      }

      #ifndef _WINDOWS
        /* find the index of the model to updae */
        p_model_path = p_database;
        model_index == -1;
        for (i=0; i<model_number; i++)
        {
          if ( strcmp(p_model_path, sr_name) == 0 )
          {
            model_index = i;
          }
          p_model_path += AUDIO_PATH_NAME_MAX_SIZE;
        }
        if (model_index == -1)
        /* no file correspoding to the model to update */
        {
          audio_sr_error_trace(AUDIO_ENTITY_FILE_ERROR);
          rvf_free_buf((T_RVF_BUFFER *)p_database);
          return (AUDIO_ERROR);
        }
      #else
        model_index = 0;
      #endif

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_SR_UPDATE_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.               */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_database);
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        rvf_free_buf((T_RVF_BUFFER *)p_database);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_SR_UPDATE_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->vocabulary_size = model_number;
      p_msg_start->model_index = model_index;
      p_msg_start->p_database = p_database;
      p_msg_start->record_speech = p_parameter->record_speech;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Speech Reco not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_sr_update_start function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_sr_update_stop                                     */
  /*                                                                              */
  /*    Purpose:  This function is called to stop the SR update   t               */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        SR update parameters                                                  */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_sr_update_stop (T_RV_RETURN return_path)
  {
    #if (SPEECH_RECO)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_SR_UPDATE_STOP   *p_msg_start  = NULL;

    /************************ audio_sr_update_start function begins ***************/

      if (p_audio_gbl_var == NULL )
      {
        audio_sr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_SR_UPDATE_STOP),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.         */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_SR_UPDATE_STOP_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Speech Reco not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_sr_update_stop function *****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_sr_reco_start                                      */
  /*                                                                              */
  /*    Purpose:  This function is called to start the SR recognition             */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        SR update parameters                                                  */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_sr_reco_start (T_AUDIO_SR_RECO_PARAMETER *p_parameter,
                                     T_RV_RETURN return_path)
  {
    #if (SPEECH_RECO)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_SR_RECO_START  *p_msg_start  = NULL;
      INT8                      model_number;
      void                      *p_database;

      /************************ audio_sr_reco_start function begins ****************/

      if (p_audio_gbl_var == NULL )
      {
        audio_sr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the / is in the end of the directory */
      if(strlen(p_parameter->database_directory) == 0)
      {
        audio_sr_error_trace(AUDIO_ENTITY_BAD_DATABASE);
        return(AUDIO_ERROR);
      }
      else if ( strncmp(&(p_parameter->database_directory[strlen(p_parameter->database_directory) - 1]),
           "/", 1) == 0 )
      {
        audio_sr_error_trace(AUDIO_ENTITY_BAD_DATABASE);
        return(AUDIO_ERROR);
      }

      /* check the number of model in the database */
      model_number = audio_sr_create_vocabulary_database(p_parameter->database_directory,
        (void **)(&p_database));
      if (model_number == AUDIO_ERROR)
      {
        audio_sr_error_trace(AUDIO_ENTITY_BAD_DATABASE);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_SR_RECO_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.               */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_database);
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        rvf_free_buf((T_RVF_BUFFER *)p_database);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_SR_RECO_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->vocabulary_size = model_number;
      p_msg_start->p_database = p_database;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Speech Reco not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_sr_reco_Start function ******************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_sr_reco_stop                                       */
  /*                                                                              */
  /*    Purpose:  This function is called to stop the SR recognition              */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        SR reco parameters                                                    */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_sr_reco_stop (T_RV_RETURN return_path)
  {
    #if (SPEECH_RECO)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS           mb_status = RVF_GREEN;
      T_AUDIO_SR_RECO_STOP   *p_msg_start  = NULL;

    /************************ audio_sr_reco_stop function begins ******************/

      if (p_audio_gbl_var == NULL )
      {
        audio_sr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_SR_RECO_STOP),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.         */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_sr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_SR_RECO_STOP_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Speech Reco not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_sr_reco_stop function *******************/

    /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_full_access_write                                  */
  /*                                                                              */
  /*    Purpose:  This function is called to configure the audio mode             */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        audio configuration                                                   */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_full_access_write (T_AUDIO_FULL_ACCESS_WRITE  *p_parameter,
                                       T_RV_RETURN                return_path)
  {
    UINT8                               size;
    INT8                                i;
    T_RVF_MB_STATUS                     mb_status = RVF_GREEN;
    T_AUDIO_MODE_FULL_ACCESS_WRITE_REQ  *p_msg_start  = NULL;
    void                                *p_data_buffer = NULL;
    INT8                                *p_read, *p_write;

    /************************ audio_full_access_write function begins ***********************/

    if (p_audio_gbl_var == NULL )
    {
      audio_mode_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    /* check if the data exist */
    if (p_parameter->data == NULL)
    {
      audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
      return(AUDIO_ERROR);
    }

    switch (p_parameter->variable_indentifier)
    {
      case AUDIO_PATH_USED:
      {
        if ( (*((T_AUDIO_VOICE_PATH_SETTING *)p_parameter->data) != AUDIO_GSM_VOICE_PATH) &&
             (*((T_AUDIO_VOICE_PATH_SETTING *)p_parameter->data) != AUDIO_BLUETOOTH_CORDLESS_VOICE_PATH) &&
             (*((T_AUDIO_VOICE_PATH_SETTING *)p_parameter->data) != AUDIO_BLUETOOTH_HEADSET) &&
             (*((T_AUDIO_VOICE_PATH_SETTING *)p_parameter->data) != AUDIO_DAI_ENCODER) &&
             (*((T_AUDIO_VOICE_PATH_SETTING *)p_parameter->data) != AUDIO_DAI_DECODER) &&
             (*((T_AUDIO_VOICE_PATH_SETTING *)p_parameter->data) != AUDIO_DAI_ACOUSTIC) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(T_AUDIO_VOICE_PATH_SETTING);
        break;
      }
      case AUDIO_MICROPHONE_MODE:
      {
        if ( (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_HANDHELD) &&
             (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_HANDFREE) &&
             (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_HEADSET) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_MICROPHONE_GAIN:
      {
        if (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_MUTE)
        {
          if ( (*((INT8  *)p_parameter->data) < -12) ||
               (*((INT8  *)p_parameter->data) > 12) )
          {
            audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
            return (AUDIO_ERROR);
          }
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_MICROPHONE_EXTRA_GAIN:
      {
        if ( (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_AUX_GAIN_28_2dB) &&
             (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_AUX_GAIN_4_6dB) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_MICROPHONE_OUTPUT_BIAS:
      {
        if ( (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_OUTPUT_BIAS_2_0V) &&
             (*((INT8  *)p_parameter->data) != AUDIO_MICROPHONE_OUTPUT_BIAS_2_5V) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_MICROPHONE_FIR:
      {
        size = sizeof(T_AUDIO_FIR_COEF);
        break;
      }
      case AUDIO_SPEAKER_MODE:
      {
        if ( (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_HANDHELD) &&
             (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_HANDFREE) &&
             (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_HEADSET) &&
             (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_BUZZER) &&
             (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_HANDHELD_HANDFREE) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_SPEAKER_GAIN:
      {
        if ( (*((INT8  *)p_parameter->data) < -6) ||
             (*((INT8  *)p_parameter->data) > 6) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_SPEAKER_FILTER:
      {
        if ( (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_FILTER_ON) &&
             (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_FILTER_OFF) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_SPEAKER_FIR:
      {
        size = sizeof(T_AUDIO_FIR_COEF);
        break;
      }
      case AUDIO_SPEAKER_BUZZER_STATE:
      {
        if ( (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_BUZZER_ON) &&
             (*((INT8  *)p_parameter->data) != AUDIO_SPEAKER_BUZZER_OFF) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_MICROPHONE_SPEAKER_LOOP_SIDETONE:
      {
        i = ((*((INT8  *)p_parameter->data))-1)%3;

        if ( (*((INT8  *)p_parameter->data) != AUDIO_SIDETONE_OPEN) &&
             ( (*((INT8  *)p_parameter->data) < -23) ||
               (*((INT8  *)p_parameter->data) > 1)   ||
               (i != 0) ) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(INT8 );
        break;
      }
      case AUDIO_MICROPHONE_SPEAKER_LOOP_AEC:
      {
        T_AUDIO_AEC_CFG *aec_param;
        aec_param = (T_AUDIO_AEC_CFG *)p_parameter->data;

      #if (L1_NEW_AEC)
        if ( ((aec_param->aec_enable != AUDIO_AEC_ENABLE) &&
              (aec_param->aec_enable != AUDIO_AEC_DISABLE)) ||
             ((aec_param->aec_visibility != AUDIO_AEC_VISIBILITY_ENABLE) &&
              (aec_param->aec_visibility != AUDIO_AEC_VISIBILITY_DISABLE)) ||
             ((aec_param->continuous_filtering != TRUE) &&
              (aec_param->continuous_filtering != FALSE)) ||
             ((aec_param->noise_suppression_enable != AUDIO_NOISE_SUPPRESSION_ENABLE) &&
              (aec_param->noise_suppression_enable != AUDIO_NOISE_SUPPRESSION_DISABLE)) ||
             ((aec_param->noise_suppression_level != AUDIO_NOISE_NO_LIMITATION) &&
              (aec_param->noise_suppression_level != AUDIO_NOISE_6dB) &&
              (aec_param->noise_suppression_level != AUDIO_NOISE_12dB) &&
              (aec_param->noise_suppression_level != AUDIO_NOISE_18dB)) )
      #else
        if ( (aec_param->aec_enable != AUDIO_AEC_ENABLE) &&
             (aec_param->aec_enable != AUDIO_AEC_DISABLE) &&
             (aec_param->aec_mode != AUDIO_SHORT_ECHO) &&
             (aec_param->aec_mode != AUDIO_LONG_ECHO) &&
             (aec_param->echo_suppression_level != AUDIO_ECHO_0dB) &&
             (aec_param->echo_suppression_level != AUDIO_ECHO_6dB) &&
             (aec_param->echo_suppression_level != AUDIO_ECHO_12dB) &&
             (aec_param->echo_suppression_level != AUDIO_ECHO_18dB) &&
             (aec_param->noise_suppression_enable != AUDIO_NOISE_SUPPRESSION_ENABLE) &&
             (aec_param->noise_suppression_enable != AUDIO_NOISE_SUPPRESSION_DISABLE) &&
             (aec_param->noise_suppression_level != AUDIO_NOISE_NO_LIMITATION) &&
             (aec_param->noise_suppression_enable != AUDIO_NOISE_6dB) &&
             (aec_param->noise_suppression_level != AUDIO_NOISE_12dB) &&
             (aec_param->noise_suppression_level != AUDIO_NOISE_18dB) )
      #endif
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(T_AUDIO_AEC_CFG);
        break;
      }
      case AUDIO_SPEAKER_VOLUME_LEVEL:
      {
        if ( (((T_AUDIO_SPEAKER_LEVEL *)p_parameter->data)->audio_speaker_level != AUDIO_SPEAKER_VOLUME_MUTE) &&
             (((T_AUDIO_SPEAKER_LEVEL *)p_parameter->data)->audio_speaker_level != AUDIO_SPEAKER_VOLUME_0dB) &&
             (((T_AUDIO_SPEAKER_LEVEL *)p_parameter->data)->audio_speaker_level != AUDIO_SPEAKER_VOLUME_6dB) &&
             (((T_AUDIO_SPEAKER_LEVEL *)p_parameter->data)->audio_speaker_level != AUDIO_SPEAKER_VOLUME_12dB) &&
             (((T_AUDIO_SPEAKER_LEVEL *)p_parameter->data)->audio_speaker_level != AUDIO_SPEAKER_VOLUME_18dB) &&
             (((T_AUDIO_SPEAKER_LEVEL *)p_parameter->data)->audio_speaker_level != AUDIO_SPEAKER_VOLUME_24dB) )
        {
          audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
          return (AUDIO_ERROR);
        }

        size = sizeof(T_AUDIO_SPEAKER_LEVEL);
        break;
      }
      default :
      {
        audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        return (AUDIO_ERROR);
      }
    }

    /* allocate the memory for the message to send */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                             sizeof (T_AUDIO_MODE_FULL_ACCESS_WRITE_REQ),
                             (T_RVF_BUFFER **) (&p_msg_start));

    /* If insufficient resources, then report a memory error and abort.               */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* allocate the memory for the data to write */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                             size,
                             (T_RVF_BUFFER **) (&p_data_buffer));

    /* If insufficient resources, then report a memory error and abort.               */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
      rvf_free_buf((T_RVF_BUFFER *)p_data_buffer);
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* fill the message parameters */
    p_msg_start->audio_parameter.data = p_data_buffer;

    p_read  = (INT8 *)(p_parameter->data);
    p_write = (INT8 *)p_data_buffer;
    for (i=0; i<size; i++)
    {
      *p_write++ = *p_read++;
    }

    p_msg_start->audio_parameter.variable_indentifier = p_parameter->variable_indentifier;

    /* fill the message id */
    p_msg_start->os_hdr.msg_id    = AUDIO_MODE_WRITE_REQ;

    /* fill the task source id */
    p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
    p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

    if (return_path.callback_func == NULL)
    {
      p_msg_start->return_path.addr_id = return_path.addr_id;
      p_msg_start->return_path.callback_func = NULL;
    }
    else
    {
      p_msg_start->return_path.callback_func = return_path.callback_func;
    }

    /* send the messsage to the audio entity */
    rvf_send_msg (p_audio_gbl_var->addrId,
                  p_msg_start);

    return (AUDIO_OK);
    /************************ Enf of audio_full_access_write function ***********************/
  }

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_full_access_read                                   */
  /*                                                                              */
  /*    Purpose:  This function is called to read the current audio mode.         */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        Status                                                                */
  /*        Audio settings                                                        */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_full_access_read (T_AUDIO_FULL_ACCESS_READ *p_parameter)
  {
    T_AUDIO_RET status = AUDIO_ERROR;

    /************************ audio_full_access_write function begins ***********************/

    if (p_audio_gbl_var == NULL )
    {
      audio_mode_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    switch (p_parameter->variable_indentifier)
    {
      case AUDIO_PATH_USED:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: voice path", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_voice_path_read((T_AUDIO_VOICE_PATH_SETTING *)p_parameter->data);
        break;
      }
      case AUDIO_MICROPHONE_MODE:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: microphone mode", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_microphone_mode_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_MICROPHONE_GAIN:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: microphone gain", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_microphone_gain_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_MICROPHONE_EXTRA_GAIN:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: microphone extra gain", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_microphone_extra_gain_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_MICROPHONE_OUTPUT_BIAS:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: output bias", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_microphone_output_bias_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_MICROPHONE_FIR:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: microphone FIR", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_microphone_fir_read((T_AUDIO_FIR_COEF *)p_parameter->data);
        break;
      }
      case AUDIO_SPEAKER_MODE:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: speaker mode", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_speaker_mode_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_SPEAKER_GAIN:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: speaker gain", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_speaker_gain_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_SPEAKER_FILTER:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: speaker filter", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_speaker_filter_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_SPEAKER_FIR:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: speaker_FIR", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_speaker_fir_read((T_AUDIO_FIR_COEF *)p_parameter->data);
        break;
      }
      case AUDIO_SPEAKER_BUZZER_STATE:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: speaker buzzer", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_speaker_buzzer_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_MICROPHONE_SPEAKER_LOOP_SIDETONE:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: sidetone gain", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_sidetone_gain_read((INT8 *)p_parameter->data);
        break;
      }
      case AUDIO_MICROPHONE_SPEAKER_LOOP_AEC:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: AEC", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_aec_read((T_AUDIO_AEC_CFG *)p_parameter->data);
        break;
      }
      case AUDIO_SPEAKER_VOLUME_LEVEL:
      {
        AUDIO_SEND_TRACE("AUDIO MODE FULL ACCESS READ: volume", RV_TRACE_LEVEL_DEBUG_LOW);
        status = audio_mode_speaker_volume_read((T_AUDIO_SPEAKER_LEVEL *)p_parameter->data);
        break;
      }
    }

    return(status);

    /************************ Enf of audio_full_access_write function ***********************/
  }

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_mode_save                                          */
  /*                                                                              */
  /*    Purpose:  This function is called to save the current audio mode.         */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        audio mode file name.                                                 */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        Status                                                                */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_mode_save (T_AUDIO_MODE_SAVE *p_parameter, T_RV_RETURN return_path)
  {
    /************************ audio_full_access_write function begins ***********************/
    char                  audio_mode_path_name[AUDIO_PATH_NAME_MAX_SIZE];
    T_FFS_FD              audio_mode_ffs_fd, audio_volume_ffs_fd;
    T_AUDIO_MODE_SAVE_REQ *p_msg_start;
    T_RVF_MB_STATUS       mb_status = RVF_GREEN;

    if (p_audio_gbl_var == NULL )
    {
      audio_mode_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    /* Create the audio mode path name */
    audio_mode_path_name[0] = 0;
    strcpy(audio_mode_path_name,"/aud/");
    strcpy(&(audio_mode_path_name[5]), p_parameter->audio_mode_filename);
    strcat(audio_mode_path_name,".cfg");

    /* Open the FFS file */
    #ifndef _WINDOWS
      audio_mode_ffs_fd = ffs_open(audio_mode_path_name,
        FFS_O_CREATE | FFS_O_WRONLY | FFS_O_TRUNC | FFS_O_APPEND);
      if (audio_mode_ffs_fd <= 0)
      {
        audio_mode_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return(AUDIO_ERROR);
    }
    #else
      audio_mode_ffs_fd = 0x00000110;
    #endif

    /* Create the volume path name */
    audio_mode_path_name[5] = 0;
    strcpy(&(audio_mode_path_name[5]), p_parameter->audio_mode_filename);
    strcat(audio_mode_path_name,".vol");

    /* Open the FFS file */
    #ifndef _WINDOWS
      audio_volume_ffs_fd = ffs_open(audio_mode_path_name,
        FFS_O_CREATE | FFS_O_WRONLY | FFS_O_TRUNC | FFS_O_APPEND);
      if (audio_volume_ffs_fd <= 0)
      {
        ffs_close(audio_mode_ffs_fd);
        audio_mode_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return(AUDIO_ERROR);
    }
    #else
      audio_volume_ffs_fd = 0x00000111;
    #endif

    /* allocate the memory for the message to send */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                             sizeof (T_AUDIO_MODE_SAVE_REQ),
                             (T_RVF_BUFFER **) (&p_msg_start));

    /* If insufficient resources, then report a memory error and abort.               */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* fill the message parameters */
    p_msg_start->audio_ffs_fd = audio_mode_ffs_fd;
    p_msg_start->audio_volume_ffs_fd = audio_volume_ffs_fd;

    /* fill the message id */
    p_msg_start->os_hdr.msg_id    = AUDIO_MODE_SAVE_REQ;

    /* fill the task source id */
    p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
    p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

    if (return_path.callback_func == NULL)
    {
      p_msg_start->return_path.addr_id = return_path.addr_id;
      p_msg_start->return_path.callback_func = NULL;
    }
    else
    {
      p_msg_start->return_path.callback_func = return_path.callback_func;
    }

    /* send the messsage to the audio entity */
    rvf_send_msg (p_audio_gbl_var->addrId,
                  p_msg_start);

    return (AUDIO_OK);
    /************************ Enf of audio_full_access_write function ***********************/
  }
  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_mode_save                                          */
  /*                                                                              */
  /*    Purpose:  This function is called to load an audio mode.                  */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        audio mode file name.                                                 */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        Status                                                                */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_mode_load (T_AUDIO_MODE_LOAD *p_parameter, T_RV_RETURN return_path)
  {
    /************************ audio_full_access_write function begins ***********************/
    char                  audio_path_name[AUDIO_PATH_NAME_MAX_SIZE];
    T_FFS_FD              audio_mode_ffs_fd, audio_volume_ffs_fd;
    T_AUDIO_MODE_LOAD_REQ *p_msg_start;
    T_RVF_MB_STATUS       mb_status = RVF_GREEN;

    if (p_audio_gbl_var == NULL )
    {
      audio_mode_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    /* Create the audio mode path name */
    audio_path_name[0] = 0;
    strcpy(audio_path_name,"/aud/");
    strcpy(&(audio_path_name[5]), p_parameter->audio_mode_filename);
    strcat(audio_path_name,".cfg");

    /* Open the FFS file */
    #ifndef _WINDOWS
      audio_mode_ffs_fd = ffs_open(audio_path_name,
        FFS_O_RDONLY);
      if (audio_mode_ffs_fd <= 0)
      {
        audio_mode_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return(AUDIO_ERROR);
      }
    #else
      audio_mode_ffs_fd = 0x00001000;
    #endif

    /* Create the volume path name */
    audio_path_name[5] = 0;
    strcpy(&(audio_path_name[5]), p_parameter->audio_mode_filename);
    strcat(audio_path_name,".vol");

    /* Open the FFS file */
    #ifndef _WINDOWS
      audio_volume_ffs_fd = ffs_open(audio_path_name,
        FFS_O_RDONLY);
      if (audio_volume_ffs_fd <= 0)
      {
        ffs_close(audio_mode_ffs_fd);
        audio_mode_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return(AUDIO_ERROR);
      }
    #else
      audio_volume_ffs_fd = 0x00001001;
    #endif

    /* allocate the memory for the message to send */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                             sizeof (T_AUDIO_MODE_LOAD_REQ),
                             (T_RVF_BUFFER **) (&p_msg_start));

    /* If insufficient resources, then report a memory error and abort. */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* fill the message parameters */
    p_msg_start->audio_ffs_fd = audio_mode_ffs_fd;
    p_msg_start->audio_volume_ffs_fd = audio_volume_ffs_fd;
    strcpy(p_msg_start->audio_volume_path_name , audio_path_name);

    /* fill the message id */
    p_msg_start->os_hdr.msg_id    = AUDIO_MODE_LOAD_REQ;

    /* fill the task source id */
    p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
    p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

    if (return_path.callback_func == NULL)
    {
      p_msg_start->return_path.addr_id = return_path.addr_id;
      p_msg_start->return_path.callback_func = NULL;
    }
    else
    {
      p_msg_start->return_path.callback_func = return_path.callback_func;
    }

    /* send the messsage to the audio entity */
    rvf_send_msg (p_audio_gbl_var->addrId,
                  p_msg_start);

    return (AUDIO_OK);
    /************************ Enf of audio_full_access_write function ***********************/
  }

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_speaker_volume                                     */
  /*                                                                              */
  /*    Purpose:  This function is called to change the current speaker volume.   */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        speaker volume command.                                               */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*        Status                                                                */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_speaker_volume (T_AUDIO_SPEAKER_VOLUME volume, T_RV_RETURN return_path)
  {
    /************************ audio_speaker_volume function begins ***********************/
    T_AUDIO_SPEAKER_VOLUME_REQ *p_msg_start;
    T_RVF_MB_STATUS       mb_status = RVF_GREEN;

    if (p_audio_gbl_var == NULL )
    {
      audio_mode_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    /* Check if an audio mode is already loaded */
    if (p_audio_gbl_var->audio_mode_var.audio_volume_var.audio_volume_path_name[0] == 0)
    {
      audio_mode_error_trace(AUDIO_ENTITY_AUDIO_MODE_NO_LOADED);
      return (AUDIO_ERROR);
    }

    /* Check parameters */
    if ( (volume.volume_action != AUDIO_SPEAKER_VOLUME_INCREASE) &&
         (volume.volume_action != AUDIO_SPEAKER_VOLUME_DECREASE) &&
         (volume.volume_action != AUDIO_SPEAKER_VOLUME_SET) )
    {
      audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
      return (AUDIO_ERROR);
    }

    if ( (volume.value != AUDIO_SPEAKER_VOLUME_MUTE) &&
         (volume.value != AUDIO_SPEAKER_VOLUME_24dB) &&
         (volume.value != AUDIO_SPEAKER_VOLUME_18dB) &&
         (volume.value != AUDIO_SPEAKER_VOLUME_12dB) &&
         (volume.value != AUDIO_SPEAKER_VOLUME_6dB)  &&
         (volume.value != AUDIO_SPEAKER_VOLUME_0dB) )
    {
      audio_mode_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
      return (AUDIO_ERROR);
    }

    /* allocate the memory for the message to send */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                             sizeof (T_AUDIO_SPEAKER_VOLUME_REQ),
                             (T_RVF_BUFFER **) (&p_msg_start));

    /* If insufficient resources, then report a memory error and abort. */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      audio_mode_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* fill the message parameters */
    p_msg_start->volume.value         = volume.value;
    p_msg_start->volume.volume_action = volume.volume_action;

    /* fill the message id */
    p_msg_start->os_hdr.msg_id    = AUDIO_SPEAKER_VOLUME_REQ;

    /* fill the task source id */
    p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
    p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

    if (return_path.callback_func == NULL)
    {
      p_msg_start->return_path.addr_id = return_path.addr_id;
      p_msg_start->return_path.callback_func = NULL;
    }
    else
    {
      p_msg_start->return_path.callback_func = return_path.callback_func;
    }

    /* send the messsage to the audio entity */
    rvf_send_msg (p_audio_gbl_var->addrId,
                  p_msg_start);

    return (AUDIO_OK);
    /************************ Enf of audio_full_access_write function ***********************/
  }


  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_melody_E2_start                                    */
  /*                                                                              */
  /*    Purpose:  This function is called to initiate the melody E2 generation    */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio Melody E2 Parameters,                                           */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the melody E2 parameters.                              */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_melody_E2_start (T_AUDIO_MELODY_E2_PARAMETER *p_parameter,
                                     T_RV_RETURN return_path)
  {
    #if (MELODY_E2)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS         mb_status    = RVF_GREEN;
      T_AUDIO_MELODY_E2_START *p_msg_start = NULL;

      T_FFS_FD               ffs_fd;

    /************************ audio_melody_E2_start function begins ****************/

      if (p_audio_gbl_var == NULL )
      {
        audio_melody_E2_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the melody E2 file exist */
      #ifndef _WINDOWS
        ffs_fd = ffs_open(p_parameter->melody_E2_name, FFS_O_RDONLY);
        if (ffs_fd <= 0)
        {
          audio_melody_E2_error_trace(AUDIO_ENTITY_FILE_ERROR);
          return (AUDIO_ERROR);
        }
      #else
        ffs_fd = 0x00001010;
      #endif

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_MELODY_E2_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.*/
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_melody_E2_error_trace(AUDIO_ENTITY_NO_MEMORY);

        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_melody_E2_error_trace(AUDIO_ENTITY_NO_MEMORY);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_MELODY_E2_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id  = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      /* the ffs_fd */
      p_msg_start->audio_E2_ffs_fd = ffs_fd;

      /* the name */
      strcpy(p_msg_start->melody_E2_parameter.melody_E2_name,
             p_parameter->melody_E2_name);

      /* the loopback */
      if ( (p_parameter->E2_loopback == AUDIO_MELODY_NO_LOOPBACK) ||
           (p_parameter->E2_loopback == AUDIO_MELODY_LOOPBACK) )
      {
        p_msg_start->melody_E2_parameter.E2_loopback = p_parameter->E2_loopback;
      }
      else
      {
        /* Wrong parameter */
        audio_melody_E2_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      /* the melody mode */
      if ( (p_parameter->melody_E2_mode == AUDIO_MELODY_GAME_MODE) ||
           (p_parameter->melody_E2_mode == AUDIO_MELODY_NORMAL_MODE) )
      {
        p_msg_start->melody_E2_parameter.melody_E2_mode = p_parameter->melody_E2_mode;
      }
      else
      {
        /* Wrong parameter */
        audio_melody_E2_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        /* close the file previously open */
        #ifndef _WINDOWS
          ffs_close(ffs_fd);
        #endif
        return (AUDIO_ERROR);
      }

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }

      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg_start);

      return (AUDIO_OK);
    #else
      AUDIO_SEND_TRACE("Melody E2 not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_melody_E2_Start function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_melody_E2_stop                                     */
  /*                                                                              */
  /*    Purpose:  This function is called to stop a melody_E2 generation          */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Audio Melody E2 Parameters,                                           */
  /*        Return path.                                                          */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the melody E2 parameters.                              */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_melody_E2_stop (T_AUDIO_MELODY_E2_STOP_PARAMETER *p_parameter,
                                    T_RV_RETURN return_path)
  {
    #if (MELODY_E2)
      /* Declare local variables.                                                 */
      T_RVF_MB_STATUS        mb_status = RVF_GREEN;
      T_AUDIO_MELODY_E2_STOP *p_msg    = NULL;

      /********************** audio_melody_E2_stop function begins ****************/

      if (p_audio_gbl_var == NULL )
      {
        audio_melody_E2_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_MELODY_E2_STOP),
                               (T_RVF_BUFFER **) (&p_msg));

      /* If insufficient resources, then report a memory error and abort */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg);
        audio_melody_E2_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else
      if (mb_status == RVF_RED)
      {
        audio_melody_E2_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg->os_hdr.msg_id = AUDIO_MELODY_E2_STOP_REQ;

      /* fill the address source id */
      p_msg->os_hdr.src_addr_id  = rvf_get_taskid();
      p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;


      /* fill the message parameters */
      /* the name */
      strcpy(p_msg->melody_E2_name,
             p_parameter->melody_E2_name);

      /* the return path */
      if (return_path.callback_func == NULL)
      {
        p_msg->return_path.addr_id = return_path.addr_id;
        p_msg->return_path.callback_func = NULL;
      }
      else
      {
        p_msg->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId,
                    p_msg);

      return (AUDIO_OK);

    #else
      AUDIO_SEND_TRACE("Melody E2 not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*********************** End of audio_melody_E2_Stop function *****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_melody_E2_load_file_instruments                    */
  /*                                                                              */
  /*    Purpose:  This function is called in order to load the instruments file   */
  /*              used in the melody E2 format (.lsi file)                        */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        File name of the melody.                                              */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the melody E2 load file instruments parameters.        */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_melody_E2_load_file_instruments (
                 T_AUDIO_MELODY_E2_LOAD_FILE_INSTR_PARAMETER *p_parameter)
  {
    #if (MELODY_E2)
      /**** Declare local variables  ****/
      #ifndef _WINDOWS
         /* FFS File descriptor type */
         T_FFS_FD     ffs_fd_1, ffs_fd_2;
         T_FFS_STAT   stat;
         T_FFS_SIZE   size = 0;

         INT8 i;

         /* basic structure of the .lsi file */
         T_AUDIO_MELODY_E2_ID_NAME file_E2;
      #endif
       /* Nb of instruments in the .lsi file */
       INT8 nb_of_instruments = 0;


      /*************** audio_melody_E2_load_file_instruments function begins ********/

      if (p_audio_gbl_var == NULL )
      {
        audio_melody_E2_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* Before to start the file download, check if the melody is OFF */
      if ((p_audio_gbl_var->melody_E2_0.state != AUDIO_MELODY_E2_IDLE ) &&
          (p_audio_gbl_var->melody_E2_1.state != AUDIO_MELODY_E2_IDLE ))
      {
         /* The instrument file can't be downloaded */
         audio_melody_E2_error_trace (AUDIO_ERROR_DOWNLOAD);
         return (AUDIO_ERROR);
      }

      /**** Find the size of the .lsi file ****/
      /* the .lsi file is stores into the flash */
      /* check if the .lsi file exists */
      #ifndef _WINDOWS

         ffs_fd_1 = ffs_open(p_parameter->melody_E2_file_name, FFS_O_RDONLY );

         if (ffs_fd_1 < EFFS_OK)
         {
            audio_melody_E2_error_trace(AUDIO_ENTITY_LOAD_FILE_INSTR_ERROR);
            return (AUDIO_ERROR);
         }

         ffs_stat(p_parameter->melody_E2_file_name,&stat);


         /* check if the file contains some data */
         if (stat.size ==0)
         {
           /* the file doesn't contains data */
           /* an error is generated */
           audio_melody_E2_error_trace(AUDIO_ENTITY_FILE_ERROR);
           return(AUDIO_ERROR);
         }

         /* the file exists and contains data */
         /* Nb of instruments in the file */
         nb_of_instruments = stat.size / (sizeof(T_AUDIO_MELODY_E2_ID_NAME));


         /**** check if the melody E2 load instruments files (.mwa file) exist ****/
         /* open the .mwa file */
          for (i=0;i< nb_of_instruments;i++)
          {
             /* Load the instruments file from the FFS */
             if (ffs_read ( ffs_fd_1,
                              (&file_E2),
                              (sizeof(INT8) + AUDIO_PATH_NAME_MAX_SIZE)) < EFFS_OK )
            {
                AUDIO_SEND_TRACE("AUDIO MELODY E2: impossible to load the .lsi file", RV_TRACE_LEVEL_ERROR);

                /* Close the file */
                ffs_close(ffs_fd_1);

                return (AUDIO_ERROR);
             }

             ffs_fd_2 = ffs_open( file_E2.melody_name,
                                  FFS_O_RDONLY );

             if (ffs_fd_2 < EFFS_OK)
             {
                AUDIO_SEND_TRACE("AUDIO MELODY E2: impossible to open the .mwa file instruments", RV_TRACE_LEVEL_ERROR);

                /* Close the .mwa file */
                ffs_close(ffs_fd_1);
                ffs_close(ffs_fd_2);

                return (AUDIO_ERROR);
             }

             /* Close the file */
             ffs_close(ffs_fd_2);
         }
         ffs_close(ffs_fd_1);
      #endif

      /* Copy the new .lsi name */
      strcpy (p_audio_gbl_var->melody_E2_load_file_instruments.instrument_file_name,
              p_parameter->melody_E2_file_name);

      /* Copy the number of instrument listed by this .lsi file */
      p_audio_gbl_var->melody_E2_load_file_instruments.nb_of_instruments
        = nb_of_instruments;

      p_audio_gbl_var->melody_E2_load_file_instruments.file_downloaded = TRUE;

      return (AUDIO_OK);

    #else
      AUDIO_SEND_TRACE("Melody E2 not compiled", RV_TRACE_LEVEL_ERROR);
      return (AUDIO_ERROR);
    #endif
  } /*************** End of audio_melody_E2_load_file_instrument function **************/


  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_amr_record_to_ffs_start/stop                       */
  /*                                                                              */
  /*    Purpose:  This function is called in order to start/stop the recording of */
  /*              a AMR-MMS in Flash                                              */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Record parameters                                                     */
  /*        Return_path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters.                                        */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_amr_record_to_ffs_start (T_AUDIO_AMR_RECORD_TO_FFS_PARAMETER *p_record_parameter,
                                             T_RV_RETURN return_path)
  {
    #if (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_RECORD_TO_FFS_START *p_msg_start = NULL;
      T_RVF_MB_STATUS                     mb_status = RVF_GREEN;
      T_FFS_FD                            ffs_fd;

      /************************ audio_amr_record_to_ffs_start function begins **************/
      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the voice memo record file already exists */
      ffs_fd = ffs_open(p_record_parameter->memo_name,
                 FFS_O_CREATE | FFS_O_WRONLY | FFS_O_TRUNC | FFS_O_APPEND);
      if ( ffs_fd <= 0)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return (AUDIO_ERROR);
      }

      /* check parameters */
      if ( ((p_record_parameter->compression_mode != AUDIO_AMR_NO_COMPRESSION_MODE ) &&
            (p_record_parameter->compression_mode != AUDIO_AMR_COMPRESSION_MODE ))||
            ((p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_4_75) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_15) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_90) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_6_70) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_40) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_95) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_10_2) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_12_2))
         )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_RECORD_TO_FFS_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_AMR_RECORD_TO_FFS_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->audio_ffs_fd       = ffs_fd;
      p_msg_start->compression_mode   = p_record_parameter->compression_mode;
      p_msg_start->memo_duration      = p_record_parameter->memo_duration;
      p_msg_start->microphone_gain    = p_record_parameter->microphone_gain;
      p_msg_start->amr_vocoder        = p_record_parameter->amr_vocoder;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_start);

      return (AUDIO_OK);
    #else // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_record_to_ffs_start function ****************/

  T_AUDIO_RET audio_amr_record_to_ffs_stop (void)
  {
    #if (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_RECORD_STOP *p_msg_stop = NULL;
      T_RVF_MB_STATUS            mb_status   = RVF_GREEN;

      /************************ audio_amr_record_to_ffs_stop function begins **************/
      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_RECORD_STOP),
                               (T_RVF_BUFFER **) (&p_msg_stop));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_stop);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_stop->os_hdr.msg_id    = AUDIO_VM_AMR_RECORD_TO_FFS_STOP_REQ;

      /* fill the address source id */
      p_msg_stop->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_stop->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_stop);

      return (AUDIO_OK);
    #else // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_record_to_ffs_stop function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_mms_record_to_ffs_start/stop                       */
  /*                                                                              */
  /*    Purpose:  This function is called in order to start/stop the recording of */
  /*              a AMR-MMS in Flash (MMS header added)                           */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Record parameters                                                     */
  /*        Return_path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters.                                        */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_mms_record_to_ffs_start (T_AUDIO_MMS_RECORD_TO_FFS_PARAMETER *p_record_parameter,
                                             T_RV_RETURN return_path)
  {
    #if (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_RECORD_TO_FFS_START *p_msg_start = NULL;
      T_RVF_MB_STATUS                     mb_status = RVF_GREEN;
      T_FFS_FD                            ffs_fd;
      UINT8                               temp[6] = "#!AMR\n";

      /************************ audio_amr_record_to_ffs_start function begins **************/
      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the voice memo record file already exists */
      ffs_fd = ffs_open(p_record_parameter->memo_name,
                 FFS_O_CREATE | FFS_O_WRONLY | FFS_O_TRUNC | FFS_O_APPEND);
      if ( ffs_fd <= 0)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return (AUDIO_ERROR);
      }

      /* check parameters */
      if ( ((p_record_parameter->compression_mode != AUDIO_AMR_NO_COMPRESSION_MODE ) &&
            (p_record_parameter->compression_mode != AUDIO_AMR_COMPRESSION_MODE ))||
            ((p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_4_75) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_15) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_90) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_6_70) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_40) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_95) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_10_2) &&
             (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_12_2))
         )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_RECORD_TO_FFS_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_AMR_RECORD_TO_FFS_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->audio_ffs_fd       = ffs_fd;
      p_msg_start->compression_mode   = p_record_parameter->compression_mode;
      p_msg_start->memo_duration      = p_record_parameter->memo_duration;
      p_msg_start->microphone_gain    = p_record_parameter->microphone_gain;
      p_msg_start->amr_vocoder        = p_record_parameter->amr_vocoder;

      // write magix string #!AMR\n
      ffs_write(ffs_fd, temp, 6);

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_start);

      return (AUDIO_OK);
    #else // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_mms_record_to_ffs_start function ****************/

  T_AUDIO_RET audio_mms_record_to_ffs_stop (void)
  {
    return audio_amr_record_to_ffs_stop();
  } /*********************** End of audio_mms_record_to_ffs_stop function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_amr_play_from_ffs_start/stop                       */
  /*                                                                              */
  /*    Purpose:  This function is called in order to start/stop the playing of   */
  /*              a AMR-MMS from Flash                                            */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Play parameters                                                       */
  /*        Return_path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters.                                        */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_amr_play_from_ffs_start (T_AUDIO_AMR_PLAY_FROM_FFS_PARAMETER *p_play_parameter,
                                             T_RV_RETURN return_path)
  {
    #if (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_PLAY_FROM_FFS_START *p_msg_start = NULL;
      T_RVF_MB_STATUS                    mb_status = RVF_GREEN;
      T_FFS_FD                           ffs_fd;

      /************************ audio_amr_play_from_ffs_start function begins **************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the voice memo play file already exists        */
      ffs_fd = ffs_open(p_play_parameter->memo_name, FFS_O_RDONLY);
      if ( ffs_fd <= 0)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_PLAY_FROM_FFS_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_AMR_PLAY_FROM_FFS_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id  = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->audio_ffs_fd        = ffs_fd;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_start);

      return (AUDIO_OK);
    #else // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_play_from_ffs_start function ****************/

  T_AUDIO_RET audio_amr_play_from_ffs_stop (void)
  {
    #if (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_PLAY_STOP *p_msg_stop = NULL;
      T_RVF_MB_STATUS                    mb_status = RVF_GREEN;

      /************************ audio_amr_play_from_ffs_stop function begins **************/
      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_PLAY_STOP),
                               (T_RVF_BUFFER **) (&p_msg_stop));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_stop);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_stop->os_hdr.msg_id    = AUDIO_VM_AMR_PLAY_FROM_FFS_STOP_REQ;

      /* fill the address source id */
      p_msg_stop->os_hdr.src_addr_id  = rvf_get_taskid();
      p_msg_stop->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_stop);

      return (AUDIO_OK);
    #else // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_play_from_ffs_stop function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_mms_play_from_ffs_start/stop                       */
  /*                                                                              */
  /*    Purpose:  This function is called in order to start/stop the playing of   */
  /*              a AMR-MMS from Flash (MMS header handled)                       */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Play parameters                                                       */
  /*        Return_path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters.                                        */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_mms_play_from_ffs_start (T_AUDIO_MMS_PLAY_FROM_FFS_PARAMETER *p_play_parameter,
                                             T_RV_RETURN return_path)
  {
    #if (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_PLAY_FROM_FFS_START *p_msg_start = NULL;
      T_RVF_MB_STATUS                    mb_status = RVF_GREEN;
      T_FFS_FD                           ffs_fd;
      UINT8                              temp[6];

      /************************ audio_amr_play_from_ffs_start function begins **************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check if the voice memo play file already exists        */
      ffs_fd = ffs_open(p_play_parameter->memo_name, FFS_O_RDONLY);
      if ( ffs_fd <= 0)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_FILE_ERROR);
        return (AUDIO_ERROR);
      }
      // read magic string #!AMR\n
      ffs_read(ffs_fd, temp, 6);

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_PLAY_FROM_FFS_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        ffs_close(ffs_fd);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_AMR_PLAY_FROM_FFS_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id  = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->audio_ffs_fd        = ffs_fd;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_start);

      return (AUDIO_OK);
    #else // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_NEW_FFS_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_mms_play_from_ffs_start function ****************/

  T_AUDIO_RET audio_mms_play_from_ffs_stop (void)
  {
    return audio_amr_play_from_ffs_stop();
  }

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_amr_record_to_ram_start/stop                       */
  /*                                                                              */
  /*    Purpose:  This function is called in order to record a MMS                */
  /*              in RAM                                                          */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Record Parameters                                                     */
  /*        Return_path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters.                                        */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_amr_record_to_ram_start (T_AUDIO_AMR_RECORD_TO_RAM_PARAMETER *p_record_parameter,
                                             T_RV_RETURN return_path)
  {
    #if (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_RECORD_TO_RAM_START *p_msg_start = NULL;
      T_RVF_MB_STATUS                     mb_status = RVF_GREEN;

      /************************ audio_amr_record_to_ram_start function begins **************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      if ( (p_record_parameter->p_buffer == NULL) ||
           ((p_record_parameter->compression_mode != AUDIO_AMR_NO_COMPRESSION_MODE ) &&
            (p_record_parameter->compression_mode != AUDIO_AMR_COMPRESSION_MODE ))||
           ((p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_4_75) &&
            (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_15) &&
            (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_90) &&
            (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_6_70) &&
            (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_40) &&
            (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_95) &&
            (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_10_2) &&
            (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_12_2))
         )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_RECORD_TO_RAM_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_AMR_RECORD_TO_RAM_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->p_buffer           = p_record_parameter->p_buffer;
      p_msg_start->compression_mode   = p_record_parameter->compression_mode;
      p_msg_start->memo_duration      = p_record_parameter->memo_duration;
      p_msg_start->microphone_gain    = p_record_parameter->microphone_gain;
      p_msg_start->amr_vocoder        = p_record_parameter->amr_vocoder;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_start);

      return (AUDIO_OK);
    #else // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_record_to_ram_start function ****************/

  T_AUDIO_RET audio_amr_record_to_ram_stop (void)
  {
    #if (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_RECORD_STOP *p_msg_stop = NULL;
      T_RVF_MB_STATUS                     mb_status = RVF_GREEN;

      /************************ audio_amr_record_to_ram_stop function begins **************/

      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_RECORD_STOP),
                               (T_RVF_BUFFER **) (&p_msg_stop));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_stop);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_stop->os_hdr.msg_id    = AUDIO_VM_AMR_RECORD_TO_RAM_STOP_REQ;

      /* fill the address source id */
      p_msg_stop->os_hdr.src_addr_id = rvf_get_taskid();
      p_msg_stop->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_stop);

      return (AUDIO_OK);
    #else // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_record_to_ram_stop function ****************/

  T_AUDIO_RET audio_amr_play_from_ram_start (T_AUDIO_AMR_PLAY_FROM_RAM_PARAMETER *p_play_parameter,
                                             T_RV_RETURN return_path)
  {
    #if (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_PLAY_FROM_RAM_START *p_msg_start = NULL;
      T_RVF_MB_STATUS                    mb_status = RVF_GREEN;

      /************************ audio_amr_play_from_ram_start function begins **************/
      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* check parameters */
      if (p_play_parameter->p_buffer == NULL)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
        return (AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_PLAY_FROM_RAM_START),
                               (T_RVF_BUFFER **) (&p_msg_start));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_start);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_start->os_hdr.msg_id    = AUDIO_VM_AMR_PLAY_FROM_RAM_START_REQ;

      /* fill the address source id */
      p_msg_start->os_hdr.src_addr_id  = rvf_get_taskid();
      p_msg_start->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* fill the message parameters */
      p_msg_start->p_buffer        = p_play_parameter->p_buffer;
      p_msg_start->buffer_size     = p_play_parameter->buffer_size;

      if (return_path.callback_func == NULL)
      {
        p_msg_start->return_path.addr_id = return_path.addr_id;
        p_msg_start->return_path.callback_func = NULL;
      }
      else
      {
        p_msg_start->return_path.callback_func = return_path.callback_func;
      }

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_start);

      return (AUDIO_OK);
    #else // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_play_from_ram_start function ****************/

  T_AUDIO_RET audio_amr_play_from_ram_stop (void)
  {
    #if (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      /* Declare local variables. */
      T_AUDIO_VM_AMR_PLAY_STOP *p_msg_stop = NULL;
      T_RVF_MB_STATUS                    mb_status = RVF_GREEN;

      /************************ audio_amr_play_from_ram_stop function begins **************/
      if (p_audio_gbl_var == NULL )
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NOT_START);
        return(AUDIO_ERROR);
      }

      /* allocate the memory for the message to send */
      mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                               sizeof (T_AUDIO_VM_AMR_PLAY_STOP),
                               (T_RVF_BUFFER **) (&p_msg_stop));

      /* If insufficient resources, then report a memory error and abort.      */
      if (mb_status == RVF_YELLOW)
      {
        /* deallocate the memory */
        rvf_free_buf((T_RVF_BUFFER *)p_msg_stop);
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }
      else if (mb_status == RVF_RED)
      {
        audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
        return (AUDIO_ERROR);
      }

      /* fill the message id */
      p_msg_stop->os_hdr.msg_id    = AUDIO_VM_AMR_PLAY_FROM_RAM_STOP_REQ;

      /* fill the address source id */
      p_msg_stop->os_hdr.src_addr_id  = rvf_get_taskid();
      p_msg_stop->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

      /* send the messsage to the audio entity */
      rvf_send_msg (p_audio_gbl_var->addrId, p_msg_stop);

      return (AUDIO_OK);
    #else // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
      AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    #endif // (AUDIO_RAM_MANAGER)&&(L1_VOICE_MEMO_AMR)
  } /*********************** End of audio_amr_play_from_ram_stop function ****************/

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_driver_init_vm_amr_record_session                  */
  /*                                                                              */
  /*    Purpose:  This function is called in order to initialize VM AMR record    */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Specific VM AMR record parameters                                     */
  /*        Driver parameters                                                     */
  /*        Return path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters                                         */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_driver_init_vm_amr_record_session(T_AUDIO_DRIVER_VM_AMR_RECORD_PARAMETER *p_record_parameter,
                                                      T_AUDIO_DRIVER_PARAMETER *p_driver_parameter,
                                                      T_RV_RETURN return_path)
  {
  #if (L1_VOICE_MEMO_AMR)
    /* Declare local variables.                                                 */
    T_RVF_MB_STATUS   mb_status = RVF_GREEN;
    T_AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION *p_msg  = NULL;

    /************************ function begins ****************/

    /* check entity started */
    if (p_audio_gbl_var == NULL )
    {
      audio_driver_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    /* If bad voice memo record parameters, then report an error and abort.*/
    if ( ((p_record_parameter->compression_mode != AUDIO_AMR_NO_COMPRESSION_MODE ) &&
          (p_record_parameter->compression_mode != AUDIO_AMR_COMPRESSION_MODE ))||
         ((p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_4_75) &&
          (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_15) &&
          (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_5_90) &&
          (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_6_70) &&
          (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_40) &&
          (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_7_95) &&
          (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_10_2) &&
          (p_record_parameter->amr_vocoder != AUDIO_AMR_VOCODER_12_2))||
         (p_driver_parameter->buffer_size < AUDIO_VM_AMR_MAX_SAMPLE_SIZE_16BIT)||
         ((p_driver_parameter->nb_buffer < 2)||
          (p_driver_parameter->nb_buffer > AUDIO_DRIVER_MAX_BUFFER_PER_SESSION))
         )
    {
      audio_driver_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
      return (AUDIO_ERROR);
    }

    /* allocate the memory for the message to send */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal,
                             sizeof (T_AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION),
                             (T_RVF_BUFFER **) (&p_msg));

    /* If insufficient resources, then report a memory error and abort.         */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg);
      audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* fill message id */
    p_msg->os_hdr.msg_id = AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION;
    p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

    /* fill the message parameters */
    p_msg->compression_mode   = p_record_parameter->compression_mode;
    p_msg->memo_duration      = p_record_parameter->memo_duration;
    p_msg->microphone_gain    = p_record_parameter->microphone_gain;
    p_msg->amr_vocoder        = p_record_parameter->amr_vocoder;

    /* fill parameters */
    p_msg->driver_parameter.buffer_size = p_driver_parameter->buffer_size;
    p_msg->driver_parameter.nb_buffer   = p_driver_parameter->nb_buffer;

    if (return_path.callback_func == NULL)
    {
      p_msg->return_path.addr_id = return_path.addr_id;
      p_msg->return_path.callback_func = NULL;
    }
    else
      p_msg->return_path.callback_func = return_path.callback_func;

    /* send the messsage to the audio entity */
    rvf_send_msg (p_audio_gbl_var->addrId, p_msg);

    return (AUDIO_OK);
  #else  // L1_VOICE_MEMO_AMR
    AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
    return (AUDIO_ERROR);
  #endif // L1_VOICE_MEMO_AMR
  }

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_driver_init_vm_amr_play_session                    */
  /*                                                                              */
  /*    Purpose:  This function is called in order to initialize VM AMR play      */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        Specific VM AMR play parameters                                       */
  /*        Driver parameters                                                     */
  /*        Return path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters                                         */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_driver_init_vm_amr_play_session(T_AUDIO_DRIVER_PARAMETER *p_driver_parameter, T_RV_RETURN return_path)
  {
  #if (L1_VOICE_MEMO_AMR)
    /* Declare local variables.                                                 */
    T_RVF_MB_STATUS   mb_status = RVF_GREEN;
    T_AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION *p_msg  = NULL;

    /************************ audio_keybeep_stop function begins ****************/

    if (p_audio_gbl_var == NULL )
    {
      audio_driver_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    /* If bad voice memo record parameters, then report an error and abort.*/
    if ( (p_driver_parameter->buffer_size < AUDIO_VM_AMR_MAX_SAMPLE_SIZE_16BIT)||
         ((p_driver_parameter->nb_buffer < 2)||
          (p_driver_parameter->nb_buffer > AUDIO_DRIVER_MAX_BUFFER_PER_SESSION))
       )
    {
      audio_driver_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
      return (AUDIO_ERROR);
    }

    /* allocate the memory for the message to send */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal,
                             sizeof (T_AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION),
                             (T_RVF_BUFFER **) (&p_msg));

    /* If insufficient resources, then report a memory error and abort.         */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg);
      audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* fill the message id */
    p_msg->os_hdr.msg_id = AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION;
    p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

    /* fill parameters */
    p_msg->driver_parameter.buffer_size = p_driver_parameter->buffer_size;
    p_msg->driver_parameter.nb_buffer   = p_driver_parameter->nb_buffer;

    if (return_path.callback_func == NULL)
    {
      p_msg->return_path.addr_id = return_path.addr_id;
      p_msg->return_path.callback_func = NULL;
    }
    else
      p_msg->return_path.callback_func = return_path.callback_func;

    /* send the messsage to the audio entity */
    rvf_send_msg (p_audio_gbl_var->addrId, p_msg);

    return (AUDIO_OK);
  #else  // L1_VOICE_MEMO_AMR
    AUDIO_SEND_TRACE("Voice Memo AMR not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
    return (AUDIO_ERROR);
  #endif // L1_VOICE_MEMO_AMR
  }

  /********************************************************************************/
  /*                                                                              */
  /*    Function Name:   audio_driver_..._session                                 */
  /*                                                                              */
  /*    Purpose:  This function is called in order to start/stop/free session     */
  /*                                                                              */
  /*    Input Parameters:                                                         */
  /*        channel identifier                                                    */
  /*        Return path                                                           */
  /*                                                                              */
  /*    Output Parameters:                                                        */
  /*         Validation of the parameters                                         */
  /*                                                                              */
  /*    Note:                                                                     */
  /*        None.                                                                 */
  /*                                                                              */
  /*    Revision History:                                                         */
  /*        None.                                                                 */
  /*                                                                              */
  /********************************************************************************/
  T_AUDIO_RET audio_driver_start_session(UINT8 channel_id, T_RV_RETURN notification_return_path)
  {
    return audio_driver_handle_session(AUDIO_DRIVER_START_SESSION, channel_id, notification_return_path);
  }

  T_AUDIO_RET audio_driver_stop_session(UINT8 channel_id)
  {
    T_RV_RETURN return_path;

    return_path.callback_func = NULL;
    return_path.addr_id       = 0;

    return audio_driver_handle_session(AUDIO_DRIVER_STOP_SESSION, channel_id, return_path);
  }

  T_AUDIO_RET audio_driver_free_session(UINT8 channel_id, T_RV_RETURN return_path)
  {
    return audio_driver_handle_session(AUDIO_DRIVER_FREE_SESSION, channel_id, return_path);
  }

  T_AUDIO_RET audio_driver_handle_session(UINT32 msg_id, UINT8 channel_id, T_RV_RETURN return_path)
  {
  #if (L1_AUDIO_DRIVER)
    /* Declare local variables.                                                 */
    T_RVF_MB_STATUS   mb_status = RVF_GREEN;
    T_AUDIO_DRIVER_HANDLE_SESSION *p_msg  = NULL;

    /************************ audio_driver_handle_session function begins ****************/

    if (p_audio_gbl_var == NULL )
    {
      audio_driver_error_trace(AUDIO_ENTITY_NOT_START);
      return(AUDIO_ERROR);
    }

    /* If bad voice memo record parameters, then report an error and abort.*/
    if (channel_id >= AUDIO_DRIVER_MAX_CHANNEL)
    {
      audio_driver_error_trace(AUDIO_ENTITY_BAD_PARAMETER);
      return (AUDIO_ERROR);
    }

    /* allocate the memory for the message to send */
    mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
                             sizeof (T_AUDIO_DRIVER_HANDLE_SESSION),
                             (T_RVF_BUFFER **) (&p_msg));

    /* If insufficient resources, then report a memory error and abort.         */
    if (mb_status == RVF_YELLOW)
    {
      /* deallocate the memory */
      rvf_free_buf((T_RVF_BUFFER *)p_msg);
      audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }
    else
    if (mb_status == RVF_RED)
    {
      audio_voice_memo_amr_error_trace(AUDIO_ENTITY_NO_MEMORY);
      return (AUDIO_ERROR);
    }

    /* fill the message id */
    p_msg->os_hdr.msg_id = msg_id;
    p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId;

    /* fill the message parameters */
    p_msg->channel_id = channel_id;

    if (return_path.callback_func == NULL)
    {
      p_msg->return_path.addr_id = return_path.addr_id;
      p_msg->return_path.callback_func = NULL;
    }
    else
      p_msg->return_path.callback_func = return_path.callback_func;

    /* send the messsage to the audio entity */
    rvf_send_msg (p_audio_gbl_var->addrId, p_msg);

    return (AUDIO_OK);
  #else
    AUDIO_SEND_TRACE("Audio Driver not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
    return(AUDIO_ERROR);
  #endif
  }

  T_AUDIO_RET audio_driver_get_play_buffer(UINT8 channel_id, UINT8 **pp_buffer)
  {
  #if (L1_AUDIO_DRIVER)
    T_AUDIO_DRIVER_SESSION *p_session;
    UINT8 index_appli;

    /* Test CHANNEL_ID */
    if (channel_id >= AUDIO_DRIVER_MAX_CHANNEL)
    {
      AUDIO_SEND_TRACE("AUDIO DRIVER GET BUFFER: channel_id not valid", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    }

    /* get driver session */
    p_session = &(p_audio_gbl_var->audio_driver_session[channel_id]);
    index_appli = p_session->session_info.index_appli;

    /* channel must be initialized */
    if (p_session->session_info.state == AUDIO_DRIVER_CHANNEL_WAIT_INIT)
    {
      AUDIO_SEND_TRACE("AUDIO DRIVER GET BUFFER: channel not initialized", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    }

    /* play buffer must have been used after a previous call of this API */
    if (p_session->session_info.play_api_state != AUDIO_PLAY_API_STATE_GET_BUF)
    {
      AUDIO_SEND_TRACE("AUDIO DRIVER GET BUFFER: PLAY not called after GET", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    }

    /* test if next buffer is available */
    if (index_appli != p_session->session_info.index_l1)
    {
      *pp_buffer = (UINT8 *)(p_session->session_info.buffer[index_appli].p_start_pointer);
      AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER GET BUFFER: buffer", *pp_buffer, RV_TRACE_LEVEL_DEBUG_LOW);
      p_session->session_info.play_api_state = AUDIO_PLAY_API_STATE_PLAY_BUF;
    }
    else
    {
      AUDIO_SEND_TRACE("AUDIO DRIVER GET BUFFER: no buffer available", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    }

    /* 1st time, index_l1 = 0xFF. At 1st play, layer1 becomes valid so we put 0
       This way, appli can't circle round buffers when in WAIT_START state */
    if (p_session->session_info.state == AUDIO_DRIVER_CHANNEL_WAIT_START)
      p_session->session_info.index_l1 = 0;

    return (AUDIO_OK);
  #else
    AUDIO_SEND_TRACE("Audio Driver not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
    return(AUDIO_ERROR);
  #endif
  }

  T_AUDIO_RET audio_driver_play_buffer(UINT8 channel_id, UINT8 *p_buffer)
  {
  #if (L1_AUDIO_DRIVER)
    T_AUDIO_DRIVER_SESSION *p_session;

    /* Test CHANNEL_ID */
    if (channel_id >= AUDIO_DRIVER_MAX_CHANNEL)
    {
      AUDIO_SEND_TRACE("AUDIO DRIVER PLAY BUFFER: channel_id not valid", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    }

    /* get driver session */
    p_session = &(p_audio_gbl_var->audio_driver_session[channel_id]);

    /* channel must be initialized */
    if (p_session->session_info.state == AUDIO_DRIVER_CHANNEL_WAIT_INIT)
    {
      AUDIO_SEND_TRACE("AUDIO DRIVER PLAY BUFFER: channel not initialized", RV_TRACE_LEVEL_DEBUG_LOW);
      //p_session->session_info.play_api_state = AUDIO_PLAY_API_STATE_GET_BUF;
      return (AUDIO_ERROR);
    }

    /* get buffer must have been called before */
    if (p_session->session_info.play_api_state != AUDIO_PLAY_API_STATE_PLAY_BUF)
    {
      AUDIO_SEND_TRACE("AUDIO DRIVER GET BUFFER: GET not called before play", RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    }

    /* check validity of buffer */
    if ( p_buffer !=
         ((UINT8 *)(p_session->session_info.buffer[p_session->session_info.index_appli].p_start_pointer)))
    {
      AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER PLAY BUFFER: buffer is not valid", p_buffer, RV_TRACE_LEVEL_DEBUG_LOW);
      return (AUDIO_ERROR);
    }

    /* increment index_appli */
    AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER PLAY BUFFER:", p_session->session_info.index_appli, RV_TRACE_LEVEL_DEBUG_LOW);
    p_session->session_info.play_api_state = AUDIO_PLAY_API_STATE_GET_BUF;
    p_session->session_info.index_appli++;

    if (p_session->session_info.index_appli == p_session->session_req.nb_buffer)
      p_session->session_info.index_appli = 0;

    return (AUDIO_OK);
  #else
    AUDIO_SEND_TRACE("Audio Driver not compiled", RV_TRACE_LEVEL_DEBUG_LOW);
    return(AUDIO_ERROR);
  #endif

  }

  T_AUDIO_RET Side_Tone_Mute()
  {
    T_RV_RETURN return_path = { NULL, 0 };
    T_AUDIO_FULL_ACCESS_WRITE audioPara;
    INT8 value = AUDIO_SIDETONE_OPEN;
    
    audioPara.variable_indentifier = AUDIO_MICROPHONE_SPEAKER_LOOP_SIDETONE;
    audioPara.data = &value;
    
    return audio_full_access_write(&audioPara, return_path);
  }
  
  void Side_Tone_Write(INT8 gain)
  {
    T_RV_RETURN return_path = { NULL, 0 };
    T_AUDIO_FULL_ACCESS_WRITE audioPara;
    INT8 value = gain;
        
    audioPara.variable_indentifier = AUDIO_MICROPHONE_SPEAKER_LOOP_SIDETONE;
    audioPara.data = &value;

    audio_full_access_write(&audioPara, return_path);
  }
  
  T_AUDIO_RET Side_Tone_Read()
  {
    T_RV_RETURN return_path = { NULL, 0 };
    T_AUDIO_FULL_ACCESS_READ audioPara;
    INT8 value;
    
    audioPara.variable_indentifier = AUDIO_MICROPHONE_SPEAKER_LOOP_SIDETONE;
    audioPara.data = &value;
    
    audio_full_access_read(&audioPara);

    return value;
  }
  
#endif // #ifdef RVM_AUDIO_MAIN_SWE
