view src/cs/services/audio/audio_api.c @ 275:79cfefc1e2b4

audio mode load: gracefully handle mode files of wrong AEC version Unfortunately our change of enabling L1_NEW_AEC (which is necessary in order to bring our Calypso ARM fw into match with the underlying DSP reality) brings along a change in the audio mode file binary format and file size - all those new tunable AEC parameters do need to be stored somewhere, after all. But we already have existing mode files in the old format, and setting AEC config to garbage when loading old audio modes (which is what would happen without the present change) is not an appealing proposition. The solution implemented in the present change is as follows: the audio mode loading code checks the file size, and if it differs from the active version of T_AUDIO_MODE, the T_AUDIO_AEC_CFG structure is cleared - set to the default (disabled AEC) for the compiled type of AEC. We got lucky in that this varying T_AUDIO_AEC_CFG structure sits at the end of T_AUDIO_MODE!
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 30 Jul 2021 02:55:48 +0000
parents 4e78acac3d88
children
line wrap: on
line source

/****************************************************************************/
/*                                                                          */
/*  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