line source
/****************************************************************************/
/* */
/* Name audio_ffs.c */
/* */
/* Function this file contains the AUDIO ffs function: */
/* */
/* */
/* Version 0.1 */
/* */
/* Date Modification */
/* ------------------------------------ */
/* 18 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"
#if (MELODY_E1) || (MELODY_E2) || (VOICE_MEMO)
#include "rvf/rvf_api.h"
#include "rv/rv_general.h"
#include "rvm/rvm_gen.h"
#include "audio/audio_api.h"
#include "audio/audio_env_i.h"
#include "audio/audio_ffs_i.h"
#include "audio/audio_structs_i.h"
#include "audio/audio_macro_i.h"
#include "rvf/rvf_target.h"
#include "audio/audio_const_i.h"
#include "audio/audio_var_i.h"
#include "audio/audio_error_hdlr_i.h"
#include "audio/audio_messages_i.h"
/* include the usefull L1 header */
#define BOOL_FLAG
#define CHAR_FLAG
#include "l1_types.h"
#include "l1audio_cust.h"
#include "l1audio_const.h"
#include "l1audio_msgty.h"
#include "l1audio_signa.h"
#include "ffs/ffs_api.h"
/********************************************************************************/
/* */
/* Function Name: audio_ffs_manager */
/* */
/* Purpose: This function is called to manage the FFS request from the */
/* audio entity */
/* */
/* Input Parameters: */
/* message from the audio entity */
/* */
/* Output Parameters: */
/* None. */
/* */
/* Note: */
/* None. */
/* */
/* Revision History: */
/* None. */
/* */
/********************************************************************************/
void audio_ffs_manager (T_RV_HDR *p_message)
{
UINT8 j, active_task, index_ffs, index_l1, *p_buffer, channel_id;
T_AUDIO_FFS_SESSION *p_session;
T_RV_HDR *p_send_message;
T_RVF_MB_STATUS mb_status;
BOOLEAN loop_mode;
#ifndef _WINDOWS
UINT16 voice_memo_size, *p_scan;
#else
UINT16 i;
UINT8 *p_mem;
#endif
UINT16 buffer_size;
T_FFS_SIZE size;
T_RV_RET status;
switch (p_message->msg_id)
{
case AUDIO_FFS_FLASH_2_RAM_START_REQ:
{
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: flash to RAM session_id",
((T_AUDIO_FFS_FLASH_2_RAM_START *)p_message)->session_id, RV_TRACE_LEVEL_DEBUG_LOW);
/* Find a free channel */
channel_id = 0;
while ( (p_audio_gbl_var->audio_ffs_session[channel_id].session_req.valid_channel) &&
(channel_id < AUDIO_FFS_MAX_CHANNEL) )
channel_id++;
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: open channel",
channel_id, RV_TRACE_LEVEL_DEBUG_LOW);
p_session =
&(p_audio_gbl_var->audio_ffs_session[channel_id]);
/* fill the request structure corresponding to the session id */
p_session->session_req.audio_ffs_fd =
((T_AUDIO_FFS_FLASH_2_RAM_START *)p_message)->audio_ffs_fd;
p_session->session_req.size =
((T_AUDIO_FFS_FLASH_2_RAM_START *)p_message)->initial_size;
p_session->session_req.loop_mode =
((T_AUDIO_FFS_FLASH_2_RAM_START *)p_message)->loop;
p_session->session_req.session_id =
((T_AUDIO_FFS_FLASH_2_RAM_START *)p_message)->session_id;
/************************************************************/
/* the FFS must download the 2 first buffers to the RAM */
/************************************************************/
for (j=0; j<2; j++)
{
/* allocate the first buffer */
p_session->session_info.buffer[j].size =
p_session->session_req.size;
mb_status = rvf_get_buf (p_audio_gbl_var->mb_audio_ffs,
p_session->session_info.buffer[j].size,
(T_RVF_BUFFER **) (&p_session->session_info.buffer[j].p_start_pointer));
/* If insufficient resources, then report a memory error and abort. */
if (mb_status == RVF_RED)
{
audio_ffs_error_trace(AUDIO_ENTITY_NO_MEMORY);
}
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: allocate buffer",
j, RV_TRACE_LEVEL_DEBUG_LOW);
/* intialize the stop pointer */
p_session->session_info.buffer[j].p_stop_pointer =
p_session->session_info.buffer[j].p_start_pointer +
(p_session->session_info.buffer[j].size);
/* Fill the buffer j while it isn't full in case of the loop back mode activated */
loop_mode = TRUE;
buffer_size = p_session->session_info.buffer[j].size;
p_buffer = (UINT8 *)p_session->session_info.buffer[j].p_start_pointer;
while ( (p_buffer < p_session->session_info.buffer[j].p_stop_pointer) &&
(loop_mode) )
{
loop_mode = p_session->session_req.loop_mode;
#ifndef _WINDOWS
size = ffs_read(p_session->session_req.audio_ffs_fd,
p_buffer,
buffer_size);
#else
size = buffer_size;
p_mem = p_buffer;
for (i=0; i<size; i++)
{
*p_mem = (UINT8)i;
p_mem++;
}
#endif
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: ffs_read size",
size, RV_TRACE_LEVEL_DEBUG_LOW);
buffer_size -= size;
p_buffer += size;
if (buffer_size != 0)
{
#ifndef _WINDOWS
/* reset the FFS pointer */
ffs_seek(p_session->session_req.audio_ffs_fd,
0,
FFS_SEEK_SET);
#endif
}
} /* while */
} /* for (j=0; j<2; j++) */
/* initialize the cust_get_pointer state machine */
p_session->session_info.cust_get_pointer_state = AUDIO_CUST_GET_POINTER_INIT;
/* inform the L1 to use the buffer 0 */
p_session->session_info.index_l1 = 0;
/* inform the FFS downloader to fill the buffer 0 when the L1 doesn't used */
p_session->session_info.index_ffs = 0;
p_session->session_req.session_mode =
AUDIO_FFS_FLASH_2_RAM_SESSION;
/* a new session is valid now */
p_session->session_req.valid_channel = TRUE;
/* Active the downloader if it is not already activated */
active_task = 0;
for (j=0; j<AUDIO_FFS_MAX_CHANNEL; j++)
{
if ( p_audio_gbl_var->audio_ffs_session[j].session_req.valid_channel )
{
active_task++;
}
}
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: active session",
active_task, RV_TRACE_LEVEL_DEBUG_LOW);
if (active_task == 1)
{
AUDIO_SEND_TRACE("AUDIO FFS MANAGER: start FFS DOWNLOADER", RV_TRACE_LEVEL_DEBUG_LOW);
/* Active asap the FFS downloader */
rvf_start_timer(AUDIO_FFS_TIMER, AUDIO_FFS_ACTIVE_NOW, AUDIO_FFS_ONE_SHOT_TIMER);
}
/* Send the message to confirm that the first buffer is downloaded */
/* allocate the message buffer */
mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal,
sizeof (T_AUDIO_FFS_INIT),
(T_RVF_BUFFER **) (&p_send_message));
/* If insufficient resources, then report a memory error and abort. */
if (mb_status == RVF_RED)
{
audio_ffs_error_trace(AUDIO_ENTITY_NO_MEMORY);
}
/* fill the header of the message */
((T_AUDIO_FFS_INIT*)(p_send_message))->os_hdr.msg_id = AUDIO_FFS_INIT_DONE;
/* fill the status parameters */
((T_AUDIO_FFS_INIT *)(p_send_message))->session_id =
((T_AUDIO_FFS_FLASH_2_RAM_START *)p_message)->session_id;
((T_AUDIO_FFS_INIT *)(p_send_message))->channel_id =
channel_id;
/* send the message to the AUDIO entity */
rvf_send_msg (p_audio_gbl_var->addrId,
p_send_message);
break;
}
case AUDIO_FFS_RAM_2_FLASH_START_REQ:
{
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: RAM to flash session_id",
((T_AUDIO_FFS_RAM_2_FLASH_START *)p_message)->session_id, RV_TRACE_LEVEL_DEBUG_LOW);
/* Find a free channel */
channel_id = 0;
while ( (p_audio_gbl_var->audio_ffs_session[channel_id].session_req.valid_channel) &&
(channel_id < AUDIO_FFS_MAX_CHANNEL) )
channel_id++;
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: open channel",
channel_id, RV_TRACE_LEVEL_DEBUG_LOW);
p_session =
&(p_audio_gbl_var->audio_ffs_session[channel_id]);
/* fill the request structure corresponding to the session id */
p_session->session_req.size =
((T_AUDIO_FFS_RAM_2_FLASH_START *)p_message)->initial_size;
p_session->session_req.loop_mode = FALSE;
p_session->session_req.audio_ffs_fd =
((T_AUDIO_FFS_RAM_2_FLASH_START *)p_message)->audio_ffs_fd;
p_session->session_req.session_mode =
AUDIO_FFS_RAM_2_FLASH_SESSION;
p_session->session_req.session_id =
((T_AUDIO_FFS_RAM_2_FLASH_START *)p_message)->session_id;
/********************* TO BE COMPLETED **********************/
/* the FFS must allocate the first buffer to the RAM */
/************************************************************/
for (j=0; j<2; j++)
{
mb_status = rvf_get_buf (p_audio_gbl_var->mb_audio_ffs,
p_session->session_req.size,
(T_RVF_BUFFER **) (&p_session->session_info.buffer[j].p_start_pointer));
/* If insufficient resources, then report a memory error and abort. */
if (mb_status == RVF_RED)
{
audio_ffs_error_trace(AUDIO_ENTITY_NO_MEMORY);
}
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: allocate buffer",
j, RV_TRACE_LEVEL_DEBUG_LOW);
/* Copy the initial size */
p_session->session_info.buffer[j].size = p_session->session_req.size;
}
/* initialize the cust_get_pointer state machine */
p_session->session_info.cust_get_pointer_state = AUDIO_CUST_GET_POINTER_INIT;
/* inform the L1 to use the buffer 0 */
p_session->session_info.index_l1 = 0;
/* inform the FFS downloader to read the buffer 0 when the L1 doesn't used */
p_session->session_info.index_ffs = 0;
/* a new session is valid now */
p_session->session_req.valid_channel = TRUE;
/* Active the downloader if it is not already activated */
active_task = 0;
for (j=0; j<AUDIO_FFS_MAX_CHANNEL; j++)
{
if ( p_audio_gbl_var->audio_ffs_session[j].session_req.valid_channel)
{
active_task++;
}
}
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: active session",
active_task, RV_TRACE_LEVEL_DEBUG_LOW);
if (active_task == 1)
{
AUDIO_SEND_TRACE("AUDIO FFS MANAGER: start FFS DOWNLOADER", RV_TRACE_LEVEL_DEBUG_LOW);
/* Active asap the FFS downloader */
rvf_start_timer(AUDIO_FFS_TIMER, AUDIO_FFS_ACTIVE_NOW, AUDIO_FFS_ONE_SHOT_TIMER);
}
/* Send the message to confirm that the first buffer is allocated */
/* allocate the message buffer */
mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal,
sizeof (T_AUDIO_FFS_INIT),
(T_RVF_BUFFER **) (&p_send_message));
/* If insufficient resources, then report a memory error and abort. */
if (mb_status == RVF_RED)
{
audio_ffs_error_trace(AUDIO_ENTITY_NO_MEMORY);
}
/* fill the header of the message */
((T_AUDIO_FFS_INIT*)(p_send_message))->os_hdr.msg_id = AUDIO_FFS_INIT_DONE;
/* fill the status parameters */
((T_AUDIO_FFS_INIT *)(p_send_message))->session_id =
((T_AUDIO_FFS_RAM_2_FLASH_START *)p_message)->session_id;
((T_AUDIO_FFS_INIT *)(p_send_message))->channel_id =
channel_id;
/* send the message to the AUDIO entity */
rvf_send_msg (p_audio_gbl_var->addrId,
p_send_message);
break;
}
case AUDIO_FFS_STOP_REQ:
{
/* Find a channel corresponding to this session */
channel_id = 0;
while ( (p_audio_gbl_var->audio_ffs_session[channel_id].session_req.session_id
!= ((T_AUDIO_FFS_STOP_REQ *)p_message)->session_id) &&
(channel_id < AUDIO_FFS_MAX_CHANNEL) )
channel_id++;
p_session = &(p_audio_gbl_var->audio_ffs_session[channel_id]);
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: stop session_id",
((T_AUDIO_FFS_STOP_REQ *)p_message)->session_id, RV_TRACE_LEVEL_DEBUG_LOW);
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: close channel",
channel_id, RV_TRACE_LEVEL_DEBUG_LOW);
/* the task is stopped */
p_session->session_req.valid_channel = FALSE;
/* the stop process depends on the session_mode and sometimes the session_id */
#if (VOICE_MEMO)
if ( (p_session->session_req.session_mode == AUDIO_FFS_RAM_2_FLASH_SESSION) &&
(((T_AUDIO_FFS_STOP_REQ *)p_message)->session_id == AUDIO_FFS_SESSION_VM_RECORD) )
{
index_l1 = p_session->session_info.index_l1;
index_ffs = p_session->session_info.index_ffs;
if (index_ffs != index_l1)
/* There's two buffers to save: one full (index_ffs) and one not full (index_l1) */
{
AUDIO_SEND_TRACE("AUDIO FFS MANAGER: end of VM record session with index_l1<>index_ffs", RV_TRACE_LEVEL_DEBUG_LOW);
#ifndef _WINDOWS
/* save the full buffer */
if ((ffs_write (p_session->session_req.audio_ffs_fd,
p_session->session_info.buffer[index_ffs].p_start_pointer,
p_session->session_req.size)) < EFFS_OK)
{
audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_SAVED);
}
/* save a part of the buffer pointed by the L1 */
voice_memo_size = 2;
p_scan = (UINT16 *)(p_session->session_info.buffer[index_l1].p_start_pointer);
while ( (*p_scan++) != SC_VM_END_MASK )
{
voice_memo_size += 2;
}
if ((ffs_write (p_session->session_req.audio_ffs_fd,
p_session->session_info.buffer[index_l1].p_start_pointer,
voice_memo_size)) < EFFS_OK)
{
audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_SAVED);
}
#endif
}
else
/* 1 buffer (not full) needs to be saved */
{
AUDIO_SEND_TRACE("AUDIO FFS MANAGER: end of VM record session with index_l1==index_ffs", RV_TRACE_LEVEL_DEBUG_LOW);
#ifndef _WINDOWS
voice_memo_size = 2;
p_scan = (UINT16*)(p_session->session_info.buffer[index_l1].p_start_pointer);
while ( (*p_scan++) != SC_VM_END_MASK )
{
voice_memo_size += 2;
}
if ((ffs_write (p_session->session_req.audio_ffs_fd,
p_session->session_info.buffer[index_l1].p_start_pointer,
voice_memo_size)) < EFFS_OK)
{
audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_SAVED);
}
#endif
} /* index_ffs != index_l1 */
}
#endif /* VOICE_MEMO */
/* deallocate the buffers */
for (j=0; j<AUDIO_MAX_FFS_BUFFER_PER_SESSION; j++)
{
status = rvf_free_buf ( (T_RVF_BUFFER *)(p_session->session_info.buffer[j].p_start_pointer) );
if (status != RVF_GREEN)
{
AUDIO_SEND_TRACE(" wrong buffer deallocated ",
RV_TRACE_LEVEL_ERROR);
}
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: deallocate buffer",
j, RV_TRACE_LEVEL_DEBUG_LOW);
}
/* Close the FFS file */
#ifndef _WINDOWS
if ( ffs_close(p_session->session_req.audio_ffs_fd) != EFFS_OK )
{
audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_CLOSE);
}
#endif
/* Send the message to confirm that the session is stopped */
/* allocate the message buffer */
mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal,
sizeof (T_AUDIO_FFS_STOP_CON),
(T_RVF_BUFFER **)(&p_send_message));
/* If insufficient resources, then report a memory error and abort. */
if (mb_status == RVF_RED)
{
audio_ffs_error_trace(AUDIO_ENTITY_NO_MEMORY);
}
/* fill the header of the message */
((T_AUDIO_FFS_STOP_CON*)(p_send_message))->os_hdr.msg_id = AUDIO_FFS_STOP_CON;
/* fill the status parameters */
((T_AUDIO_FFS_STOP_CON*)(p_send_message))->session_id =
((T_AUDIO_FFS_STOP_REQ *)p_message)->session_id;
/* send the message to the AUDIO entity */
rvf_send_msg (p_audio_gbl_var->addrId,
p_send_message);
break;
}
} /* switch (p_message) */
}
/********************************************************************************/
/* */
/* Function Name: audio_ffs_downloader */
/* */
/* Purpose: This function is called to download the melody, voice memo data */
/* between the RAM and the FLASH. */
/* */
/* Input Parameters: */
/* None. */
/* */
/* Output Parameters: */
/* None. */
/* */
/* Note: */
/* None. */
/* */
/* Revision History: */
/* None. */
/* */
/********************************************************************************/
void audio_ffs_downloader(void)
{
UINT8 i, index_ffs, index_l1, *p_buffer;
T_AUDIO_FFS_SESSION *p_session;
UINT16 buffer_size;
T_FFS_SIZE size = 0;
BOOLEAN loop_mode, active_session;
/* Scan all session in order to know which is valid */
active_session = FALSE;
for (i=0; i<AUDIO_FFS_MAX_CHANNEL; i++)
{
p_session = &(p_audio_gbl_var->audio_ffs_session[i]);
if (p_session->session_req.valid_channel)
{
/* a session is valid */
active_session = TRUE;
index_l1 = p_session->session_info.index_l1;
index_ffs = p_session->session_info.index_ffs;
if (index_l1 != index_ffs)
/* It's time to download a new buffer for the L1 */
{
AUDIO_SEND_TRACE_PARAM("AUDIO FFS DOWNLOADER: index_l1",
index_l1, RV_TRACE_LEVEL_DEBUG_LOW);
AUDIO_SEND_TRACE_PARAM("AUDIO FFS DOWNLOADER: index_ffs",
index_ffs, RV_TRACE_LEVEL_DEBUG_LOW);
switch (p_session->session_req.session_mode)
{
case AUDIO_FFS_FLASH_2_RAM_SESSION:
{
AUDIO_SEND_TRACE("AUDIO FFS DOWNLOADER: FLASH to RAM", RV_TRACE_LEVEL_DEBUG_LOW);
/* Fill the buffer 0 while it isn't full in case of the loop back mode activated */
loop_mode = TRUE;
buffer_size = p_session->session_info.buffer[index_ffs].size;
p_buffer = (UINT8 *)p_session->session_info.buffer[index_ffs].p_start_pointer;
while ( (p_buffer < p_session->session_info.buffer[index_ffs].p_stop_pointer) &&
(loop_mode) )
{
loop_mode = p_session->session_req.loop_mode;
#ifndef _WINDOWS
size = ffs_read(p_session->session_req.audio_ffs_fd,
p_buffer,
buffer_size);
#endif
AUDIO_SEND_TRACE_PARAM("AUDIO FFS MANAGER: ffs_read size",
size, RV_TRACE_LEVEL_DEBUG_LOW);
buffer_size -= size;
p_buffer += size;
if (buffer_size != 0)
{
#ifndef _WINDOWS
/* reset the FFS pointer */
ffs_seek(p_session->session_req.audio_ffs_fd,
0,
FFS_SEEK_SET);
#endif
}
} /* while */
break;
}
case AUDIO_FFS_RAM_2_FLASH_SESSION:
{
AUDIO_SEND_TRACE("AUDIO FFS DOWNLOADER: RAM to FLASH", RV_TRACE_LEVEL_DEBUG_LOW);
/* save the full buffer */
#ifndef _WINDOWS
if ((ffs_write (p_session->session_req.audio_ffs_fd,
p_session->session_info.buffer[index_ffs].p_start_pointer,
p_session->session_req.size)) < EFFS_OK)
{
audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_SAVED);
}
#endif
break;
}
} /* switch (p_session->session_req.session_mode) */
/* update the ffs buffer index */
p_session->session_info.index_ffs++;
if (p_session->session_info.index_ffs == AUDIO_MAX_FFS_BUFFER_PER_SESSION)
{
p_session->session_info.index_ffs = 0;
}
} /* (p_session->session_info.index_l1 != p_session->session_info.index_l1) */
} /* valid session */
} /* for (i=0; i<AUDIO_FFS_MAX_CHANNEL; i++) */
/* Activate or not the Timer the next time */
if (active_session)
{
rvf_start_timer(AUDIO_FFS_TIMER, AUDIO_FFS_TIME_OUT, AUDIO_FFS_ONE_SHOT_TIMER);
}
else
{
AUDIO_SEND_TRACE("AUDIO FFS DOWNLOADER: stop", RV_TRACE_LEVEL_DEBUG_LOW);
/* Stop asap the FFS downloader */
rvf_stop_timer(AUDIO_FFS_TIMER);
}
}
#endif /* MELODY_E1 || MELODY_E2 || VOICE_MEMO */
#if (L1_VOICE_MEMO_AMR)
T_AUDIO_RET audio_convert_to_mms(UINT8 *p_buffer, UINT16 *buffer_size, UINT8 *previous_type, UINT8 *size_left)
{
UINT8 rxtx_type, frame_header, data_size;
UINT8 frame_type, quality;
UINT8 *ptr_final, *ptr_mms;
ptr_mms = p_buffer;
ptr_final = ptr_mms + *buffer_size;
/* sample is shared among the 2 buffers */
if (*size_left > 0)
{
UINT8 i;
switch (*previous_type)
{
case AUDIO_VM_AMR_RXTX_SID_FIRST:
/* set data bits to 0 */
for (i = 0; i < *size_left; i++)
*(ptr_mms + i) = 0;
/* set Mode Indication */
*(ptr_mms + *size_left - 1) = AUDIO_MMS_MODE_INDICATION;
break;
case AUDIO_VM_AMR_RXTX_SID_UPDATE:
//case AUDIO_VM_AMR_RXTX_SID_BAD:
*(ptr_mms + *size_left - 1) |= AUDIO_MMS_STI_BIT | AUDIO_MMS_MODE_INDICATION;
break;
}
ptr_mms += *size_left;
}
*size_left = 0;
while (ptr_mms < ptr_final)
{
/* read header */
frame_header = *ptr_mms;
/* if end_mask, stop */
if (frame_header == SC_VM_AMR_END_MASK)
{
*buffer_size = (ptr_mms - p_buffer);
return AUDIO_OK;
}
/* reset header */
*ptr_mms = 0;
rxtx_type = (frame_header & SC_RX_TX_TYPE_MASK);
*previous_type = rxtx_type;
switch (rxtx_type)
{
case AUDIO_VM_AMR_RXTX_SPEECH_GOOD:
//case AUDIO_VM_AMR_RXTX_SPEECH_BAD:
{
/* FT + data_size */
frame_type = frame_header & SC_CHAN_TYPE_MASK;
switch (frame_type)
{
case AUDIO_VM_AMR_SPEECH_475:
data_size = AUDIO_VM_AMR_SPEECH_475_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_515:
data_size = AUDIO_VM_AMR_SPEECH_515_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_59:
data_size = AUDIO_VM_AMR_SPEECH_590_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_67:
data_size = AUDIO_VM_AMR_SPEECH_670_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_74:
data_size = AUDIO_VM_AMR_SPEECH_740_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_795:
data_size = AUDIO_VM_AMR_SPEECH_795_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_102:
data_size = AUDIO_VM_AMR_SPEECH_102_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_122:
data_size = AUDIO_VM_AMR_SPEECH_122_DATA_SIZE;
break;
}
/* Q */
//if (rxtx_type == AUDIO_VM_AMR_RXTX_SPEECH_GOOD)
quality = AUDIO_MMS_GOOD_QUALITY;
//else
// quality = AUDIO_MMS_BAD_QUALITY;
}
break;
case AUDIO_VM_AMR_RXTX_SID_FIRST:
case AUDIO_VM_AMR_RXTX_SID_UPDATE:
//case AUDIO_VM_AMR_RXTX_SID_BAD:
{
/* FT, data_size, Q */
frame_type = AUDIO_MMS_SID_FRAME_TYPE;
data_size = AUDIO_VM_AMR_SID_DATA_SIZE;
//if ((rxtx_type == AUDIO_VM_AMR_RXTX_SID_FIRST)||
// (rxtx_type == AUDIO_VM_AMR_RXTX_SID_UPDATE))
//{
quality = AUDIO_MMS_GOOD_QUALITY;
//}
//else
// quality = AUDIO_MMS_BAD_QUALITY;
/* data, STI, Mode indication */
if (rxtx_type == AUDIO_VM_AMR_RXTX_SID_FIRST)
{
UINT8 data, i;
/* number of bytes to set to 0 */
data = ((ptr_final - ptr_mms) >= (data_size + 1)) ? (data_size) : (ptr_final - ptr_mms - 1);
/* set data bits to 0 */
for (i = 0; i < data; i++)
*(ptr_mms + 1 + i) = 0;
/* set Mode indication */
if ((ptr_final - ptr_mms) >= (data_size + 1))
*(ptr_mms + data_size) = AUDIO_MMS_MODE_INDICATION;
}
/* SID_UPDATE */
else
{
/* set STI bit to 1 + Mode indication */
if ((ptr_final - ptr_mms) >= (data_size + 1))
*(ptr_mms + data_size) |= AUDIO_MMS_STI_BIT | AUDIO_MMS_MODE_INDICATION;
}
}
break;
case AUDIO_VM_AMR_RXTX_NO_DATA:
frame_type = AUDIO_MMS_NO_DATA_FRAME_TYPE;
data_size = AUDIO_VM_AMR_NO_DATA_DATA_SIZE;
quality = AUDIO_MMS_GOOD_QUALITY;
break;
default:
{
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: convert to MMS, header not recognized", frame_header, RV_TRACE_LEVEL_DEBUG_LOW);
return AUDIO_ERROR;
}
}
/* write header */
*(ptr_mms)++ |= (frame_type << AUDIO_MMS_FRAME_TYPE_SHIFT) | (quality << AUDIO_MMS_QUALITY_SHIFT);
/* write data, check we are not at the end of the buffer */
if ((ptr_final - ptr_mms) < data_size)
{
*size_left = data_size - (ptr_final - ptr_mms);
data_size = ptr_final - ptr_mms;
}
ptr_mms += data_size;
}
*buffer_size = (ptr_final - p_buffer);
return AUDIO_OK;
}
T_AUDIO_RET audio_convert_from_mms(UINT8 *p_buffer, UINT16 buffer_size, UINT8 *previous_type, UINT8 *size_left)
{
UINT8 frame_header, data_size;
UINT8 frame_type, quality;
UINT8 *ptr_final, *ptr_mms;
ptr_mms = p_buffer;
ptr_final = ptr_mms + buffer_size;
/* a sample is split between 2 RAM buffers */
if (*size_left > 0)
{
/* if SID sample, remove STI and mode indication */
if (*previous_type == AUDIO_MMS_SID_FRAME_TYPE)
{
*(ptr_mms + *size_left - 1) &= (~(AUDIO_MMS_STI_BIT | AUDIO_MMS_MODE_INDICATION));
}
ptr_mms += *size_left;
*size_left = 0;
}
while (ptr_mms < ptr_final)
{
/* read header */
frame_header = *ptr_mms;
/* reset header */
*ptr_mms = 0;
/* FT and Q */
frame_type = (frame_header & AUDIO_MMS_FRAME_TYPE_MASK) >> AUDIO_MMS_FRAME_TYPE_SHIFT;
quality = (frame_header & AUDIO_MMS_QUALITY_MASK) >> AUDIO_MMS_QUALITY_SHIFT;
*previous_type = frame_type;
/* Identify sample */
if (frame_type < AUDIO_MMS_SID_FRAME_TYPE)
{
/* speech good or bad */
*ptr_mms |= frame_type;
if (quality == AUDIO_MMS_GOOD_QUALITY)
*ptr_mms |= AUDIO_VM_AMR_RXTX_SPEECH_GOOD;
else
*ptr_mms |= AUDIO_VM_AMR_RXTX_SPEECH_BAD;
switch (frame_type)
{
case AUDIO_VM_AMR_SPEECH_475:
data_size = AUDIO_VM_AMR_SPEECH_475_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_515:
data_size = AUDIO_VM_AMR_SPEECH_515_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_59:
data_size = AUDIO_VM_AMR_SPEECH_590_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_67:
data_size = AUDIO_VM_AMR_SPEECH_670_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_74:
data_size = AUDIO_VM_AMR_SPEECH_740_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_795:
data_size = AUDIO_VM_AMR_SPEECH_795_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_102:
data_size = AUDIO_VM_AMR_SPEECH_102_DATA_SIZE;
break;
case AUDIO_VM_AMR_SPEECH_122:
data_size = AUDIO_VM_AMR_SPEECH_122_DATA_SIZE;
break;
}
}
else if (frame_type == AUDIO_MMS_SID_FRAME_TYPE)
{
data_size = AUDIO_VM_AMR_SID_DATA_SIZE;
/* SID_BAD */
if (quality == AUDIO_MMS_BAD_QUALITY)
*ptr_mms |= AUDIO_VM_AMR_RXTX_SID_BAD;
/* SID_FIRST or SID_UPDATE */
else
{
if (*previous_type == AUDIO_MMS_NO_DATA_FRAME_TYPE)
*ptr_mms |= AUDIO_VM_AMR_RXTX_SID_UPDATE;
else
*ptr_mms |= AUDIO_VM_AMR_RXTX_SID_FIRST;
/* try to remove STI + mode indication if sample not split between 2 buffers */
if ((ptr_final - ptr_mms) >= (data_size + 1))
*(ptr_mms + data_size) &= (~(AUDIO_MMS_STI_BIT | AUDIO_MMS_MODE_INDICATION));
}
}
else if (frame_type == AUDIO_MMS_NO_DATA_FRAME_TYPE)
{
data_size = AUDIO_VM_AMR_NO_DATA_DATA_SIZE;
*ptr_mms |= AUDIO_VM_AMR_RXTX_NO_DATA;
}
else
{
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: convert from MMS, header not recognized", frame_header, RV_TRACE_LEVEL_DEBUG_LOW);
return AUDIO_ERROR;
}
/* pass header */
ptr_mms++;
/* write data, check we are not at the end of the buffer */
if ((ptr_final - ptr_mms) < data_size)
{
*size_left = data_size - (ptr_final - ptr_mms);
data_size = ptr_final - ptr_mms;
}
ptr_mms += data_size;
}
return AUDIO_OK;
}
#endif
#if (AUDIO_RAM_MANAGER)
/* try to copy "size" bytes from audio_ram_fd to dest_buffer, returns bytes copied (0 to size) */
INT16 ram_read(T_AUDIO_MEM_SESSION *p_session, UINT8 *dest_buffer, UINT16 size)
{
UINT16 i;
/* check how many bytes there are in audio_ram_fd */
if (size > p_session->session_req.audio_ram_size)
size = p_session->session_req.audio_ram_size;
/* copy byte by byte */
for (i = 0; i < size; i++)
*dest_buffer++ = *(p_session->session_req.audio_ram_fd)++;
/* update audio_ram_fd size */
p_session->session_req.audio_ram_size -= size;
return size;
}
/* copy "size" bytes from src_buffer to audio_ram_fd, does not check size */
INT16 ram_write(T_AUDIO_MEM_SESSION *p_session, UINT8 *src_buffer, UINT16 size)
{
UINT16 i;
/* copy byte by byte */
for (i = 0; i < size; i++)
*(p_session->session_req.audio_ram_fd)++ = *src_buffer++;
return size;
}
#endif
#if (AUDIO_MEM_MANAGER)
void audio_mem_send_status(T_AUDIO_RET status, UINT8 channel_id, UINT8 status_type,
T_RV_RETURN return_path)
{
/* status_type START or STOP, status AUDIO_OK or AUDIO_ERROR */
T_AUDIO_MEM_STATUS *p_send_message;
T_RVF_MB_STATUS mb_status = RVF_RED;
while (mb_status == RVF_RED)
{
/* allocate the message buffer */
mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
sizeof (T_AUDIO_MEM_STATUS),
(T_RVF_BUFFER **) (&p_send_message));
/* If insufficient resources, then report a memory error and abort. */
/* and wait until more ressource is given */
if (mb_status == RVF_RED)
{
audio_mem_error_trace(AUDIO_ENTITY_NO_MEMORY);
rvf_delay(RVF_MS_TO_TICKS(1000));
}
}
/*fill the header of the message */
p_send_message->os_hdr.msg_id = AUDIO_MEM_STATUS_MSG;
/* fill the status parameters */
p_send_message->status = status;
p_send_message->channel_id = channel_id;
p_send_message->status_type = status_type;
/* send message or call callback */
if (return_path.callback_func == NULL)
rvf_send_msg (return_path.addr_id, p_send_message);
else
{
(*return_path.callback_func)((void *)(p_send_message));
rvf_free_buf((T_RVF_BUFFER *)p_send_message);
}
}
void audio_mem_send_record_status(UINT8 channel_id, UINT32 recorded_size, T_RV_RETURN return_path)
{
/* status_type START or STOP, status AUDIO_OK or AUDIO_ERROR */
T_AUDIO_MEM_STATUS *p_send_message;
T_RVF_MB_STATUS mb_status = RVF_RED;
while (mb_status == RVF_RED)
{
/* allocate the message buffer */
mb_status = rvf_get_buf (p_audio_gbl_var->mb_external,
sizeof (T_AUDIO_MEM_STATUS),
(T_RVF_BUFFER **) (&p_send_message));
/* If insufficient resources, then report a memory error and abort. */
/* and wait until more ressource is given */
if (mb_status == RVF_RED)
{
audio_mem_error_trace(AUDIO_ENTITY_NO_MEMORY);
rvf_delay(RVF_MS_TO_TICKS(1000));
}
}
/*fill the header of the message */
p_send_message->os_hdr.msg_id = AUDIO_MEM_STATUS_MSG;
/* fill the status parameters */
p_send_message->status = AUDIO_OK;
p_send_message->channel_id = channel_id;
p_send_message->status_type = AUDIO_STOP_STATUS;
p_send_message->recorded_size = recorded_size;
/* send message or call callback */
if (return_path.callback_func == NULL)
rvf_send_msg (return_path.addr_id, p_send_message);
else
{
(*return_path.callback_func)((void *)(p_send_message));
rvf_free_buf((T_RVF_BUFFER *)p_send_message);
}
}
void audio_mem_manager (T_RV_HDR *p_message)
{
UINT8 channel_id, session_id, state;
UINT8 mem_channel_id;
T_RV_RETURN return_path;
T_AUDIO_MEM_SESSION *p_session;
/* get channel_id from messages */
switch (p_message->msg_id)
{
case AUDIO_MEM_START_REQ:
channel_id = ((T_AUDIO_MEM_START *)p_message)->channel_id;
session_id = ((T_AUDIO_MEM_START *)p_message)->session_id;
break;
case AUDIO_MEM_STOP_REQ:
channel_id = ((T_AUDIO_MEM_STOP *)p_message)->channel_id;
break;
case AUDIO_DRIVER_NOTIFICATION_MSG:
channel_id = ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id;
break;
case AUDIO_DRIVER_LAST_NOTIFICATION_MSG:
channel_id = ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id;
break;
case AUDIO_DRIVER_STATUS_MSG:
channel_id = ((T_AUDIO_DRIVER_STATUS *)p_message)->channel_id;
break;
}
/* Init mem_channel_id to browse all mem channels and find channel_id */
/* state will stay IDLE if no mem channel is found */
mem_channel_id = 0;
state = AUDIO_MEM_IDLE;
/* look for an ACTIVE session, which channel_id matches the one from the message */
while ( (mem_channel_id < AUDIO_MEM_MAX_CHANNEL)&&
((p_audio_gbl_var->audio_mem_session[mem_channel_id].session_info.state == AUDIO_MEM_IDLE)||
(p_audio_gbl_var->audio_mem_session[mem_channel_id].session_req.channel_id != channel_id)) )
{
mem_channel_id++;
}
/* if mem_channel_id < MAX_CHANNEL, we found an active channel so we can derive state */
if (mem_channel_id < AUDIO_MEM_MAX_CHANNEL)
{
p_session = &(p_audio_gbl_var->audio_mem_session[mem_channel_id]);
state = p_session->session_info.state;
}
switch (state)
{
case AUDIO_MEM_IDLE:
{
/* requester return_path (currently is Riviera Audio) */
return_path.callback_func = NULL;
return_path.addr_id = p_audio_gbl_var->addrId;
switch (p_message->msg_id)
{
case AUDIO_MEM_START_REQ:
{
/* find free MEM channel i.e. state = AUDIO_MEM_IDLE */
mem_channel_id = 0;
while ( (p_audio_gbl_var->audio_mem_session[mem_channel_id].session_info.state != AUDIO_MEM_IDLE) &&
(mem_channel_id < AUDIO_MEM_MAX_CHANNEL) )
mem_channel_id++;
if (mem_channel_id == AUDIO_MEM_MAX_CHANNEL)
{
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER: no memory channel available", RV_TRACE_LEVEL_DEBUG_LOW);
audio_mem_send_status(AUDIO_ERROR, channel_id, AUDIO_START_STATUS, return_path);
return;
}
/* get MEM session */
p_session = &(p_audio_gbl_var->audio_mem_session[mem_channel_id]);
/* fill parameters */
p_session->session_req.channel_id = channel_id;
p_session->session_req.session_id = session_id;
#if (AUDIO_NEW_FFS_MANAGER)
p_session->session_req.audio_ffs_fd =
((T_AUDIO_MEM_START *)p_message)->audio_ffs_fd;
#endif
#if (AUDIO_RAM_MANAGER)
p_session->session_req.audio_ram_fd =
((T_AUDIO_MEM_START *)p_message)->audio_ram_fd;
p_session->session_req.audio_ram_size =
((T_AUDIO_MEM_START *)p_message)->audio_ram_size;
#endif
p_session->session_req.size =
((T_AUDIO_MEM_START *)p_message)->size;// temporary RAM buffer size
/* parameters for notification handling */
p_session->session_info.size_left = 0;
p_session->session_info.previous_type = AUDIO_VM_AMR_RXTX_SPEECH_GOOD;
p_session->session_info.stop_req_allowed = TRUE;
/* initialization phase for play sessions */
switch (session_id)
{
case AUDIO_VM_AMR_PLAY_SESSION_ID:
{
UINT8 *play_buffer;// temporary RAM buffer to fill
INT16 size_read;
/* fill all buffers in advance */
while (audio_driver_get_play_buffer(channel_id, &play_buffer) == AUDIO_OK)
{
#if (AUDIO_NEW_FFS_MANAGER)
/* write from FLASH to RAM buffer */
if (p_session->session_req.audio_ffs_fd != NULL)
{
/* copy from Flash "size" bytes into play_buffer */
size_read = ffs_read(p_session->session_req.audio_ffs_fd,
play_buffer,
p_session->session_req.size);
/* wrong read */
if (size_read < EFFS_OK)
{
if ( ffs_close(p_session->session_req.audio_ffs_fd) != EFFS_OK )
audio_mem_error_trace(AUDIO_ENTITY_FILE_NO_CLOSE);
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER INIT: FFS PLAY READ failed", RV_TRACE_LEVEL_DEBUG_LOW);
audio_mem_send_status(AUDIO_ERROR, channel_id, AUDIO_START_STATUS, return_path);
return;
}
}
#endif
#if (AUDIO_RAM_MANAGER)
/* write from RAM to RAM buffer */
if (p_session->session_req.audio_ram_fd != NULL)
{
/* copy from RAM "size" bytes into play_buffer */
size_read = ram_read(p_session, play_buffer, p_session->session_req.size);
}
#endif
/* convert to MMS */
if (audio_convert_from_mms(play_buffer, size_read,
&(p_session->session_info.previous_type),
&(p_session->session_info.size_left)) != AUDIO_OK)
{
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER INIT: wrong MMS format", RV_TRACE_LEVEL_DEBUG_LOW);
size_read = 0;// will fill buffer with END_MASK and stop task
}
/* last buffer already, put END_MASK */
if ( ((UINT16)size_read) < p_session->session_req.size )
{
UINT16 i;
if (p_session->session_info.size_left != 0)
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY DOWNLOADER: MMS PLAY file incomplete",
p_session->session_info.size_left, RV_TRACE_LEVEL_DEBUG_LOW);
for (i = size_read; i < p_session->session_req.size; i++)
*(play_buffer + i) = SC_VM_AMR_END_MASK;
}
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY DOWNLOADER: size read", size_read, RV_TRACE_LEVEL_DEBUG_LOW);
audio_driver_play_buffer(channel_id, play_buffer);
}
}// case AUDIO_VM_AMR_PLAY_SESSION_ID
break;
}// switch (session_id)
audio_driver_start_session(channel_id, return_path);
p_session->session_info.state = AUDIO_MEM_WAIT_NOTIFICATION_OR_STOP;
}
break; //case AUDIO_MEM_START_REQ:
case AUDIO_MEM_STOP_REQ:
audio_mem_error_trace(AUDIO_ERROR_STOP_EVENT);
break;
}
} // case AUDIO_MEM_IDLE:
break;
case AUDIO_MEM_WAIT_NOTIFICATION_OR_STOP:
{
/* requester return_path (currently is Riviera Audio) */
return_path.callback_func = NULL;
return_path.addr_id = p_audio_gbl_var->addrId;
switch (p_message->msg_id)
{
case AUDIO_DRIVER_NOTIFICATION_MSG:
{
switch (p_session->session_req.session_id)
{
case AUDIO_VM_AMR_RECORD_SESSION_ID:
{
UINT16 record_buffer_size;
/* default is session_req.size but can be less if we find END_MASK */
record_buffer_size = p_session->session_req.size;
/* convert to MMS, update record_buffer_size if END_MASK is found */
audio_convert_to_mms((UINT8 *)((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer,
&record_buffer_size,
&(p_session->session_info.previous_type),
&(p_session->session_info.size_left));
#if (AUDIO_NEW_FFS_MANAGER)
if (p_session->session_req.audio_ffs_fd != NULL)
{
if ((ffs_write (p_session->session_req.audio_ffs_fd,
(UINT8 *)((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer,
record_buffer_size)) < EFFS_OK)
{
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER: FFS RECORD WRITE FAILED", RV_TRACE_LEVEL_DEBUG_LOW);
}
}
#endif
#if (AUDIO_RAM_MANAGER)
if (p_session->session_req.audio_ram_fd != NULL)
{
ram_write (p_session,
(UINT8 *)((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer,
record_buffer_size);
}
#endif
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: RAM to MEMORY", record_buffer_size, RV_TRACE_LEVEL_DEBUG_LOW);//DEBUG
}
break;
case AUDIO_VM_AMR_PLAY_SESSION_ID:
{
UINT8 *play_buffer;
INT16 size_read;
/* try to get a buffer */
if (audio_driver_get_play_buffer(channel_id, &play_buffer) == AUDIO_OK)
{
#if (AUDIO_NEW_FFS_MANAGER)
if (p_session->session_req.audio_ffs_fd != NULL)
{
size_read = ffs_read(p_session->session_req.audio_ffs_fd,
play_buffer,
p_session->session_req.size);
/* wrong read */
if (size_read < EFFS_OK)
{
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER: FFS PLAY READ FAILED", RV_TRACE_LEVEL_DEBUG_LOW);
size_read = 0;// will put END_MASK in whole buffer so stops play
}
}
#endif
#if (AUDIO_RAM_MANAGER)
if (p_session->session_req.audio_ram_fd != NULL)
{
size_read = ram_read(p_session, play_buffer, p_session->session_req.size);
}
#endif
if (audio_convert_from_mms(play_buffer, size_read,
&(p_session->session_info.previous_type),
&(p_session->session_info.size_left)) != AUDIO_OK)
{
AUDIO_SEND_TRACE("AUDIO MEMORY DOWNLOADER: wrong MMS format", RV_TRACE_LEVEL_DEBUG_LOW);
size_read = 0;// will fill buffer with END_MASK
}
/* last buffer, put END_MASK */
if ( ((UINT16)size_read) < p_session->session_req.size )
{
UINT16 i;
if (p_session->session_info.size_left != 0)
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: MMS PLAY file incomplete",
p_session->session_info.size_left, RV_TRACE_LEVEL_DEBUG_LOW);
for (i = size_read; i < p_session->session_req.size; i++)
*(play_buffer + i) = SC_VM_AMR_END_MASK;
}
audio_driver_play_buffer(channel_id, play_buffer);
if (size_read > 0)
{
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: MEMORY to RAM", size_read, RV_TRACE_LEVEL_DEBUG_LOW);//DEBUG
}
else
{
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER: buffer not used", RV_TRACE_LEVEL_DEBUG_LOW);//DEBUG
}
} // if (audio_driver_get_play_buffer(channel_id, &p_buffer) == AUDIO_OK)
else
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER: no buffer available", RV_TRACE_LEVEL_DEBUG_LOW);//DEBUG
}
break;
}
}
break;
case AUDIO_DRIVER_LAST_NOTIFICATION_MSG:
{
UINT16 record_buffer_size;
record_buffer_size = p_session->session_req.size;
audio_convert_to_mms((UINT8 *)((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer,
&record_buffer_size,
&(p_session->session_info.previous_type),
&(p_session->session_info.size_left));
#if (AUDIO_NEW_FFS_MANAGER)
if (p_session->session_req.audio_ffs_fd != NULL)
{
if ((ffs_write (p_session->session_req.audio_ffs_fd,
(UINT8 *)((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer,
record_buffer_size)) < EFFS_OK)
{
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER: FFS RECORD WRITE FAILED", RV_TRACE_LEVEL_DEBUG_LOW);
}
}
#endif
#if (AUDIO_RAM_MANAGER)
if (p_session->session_req.audio_ram_fd != NULL)
{
if ((ram_write (p_session,
(UINT8 *)((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer,
record_buffer_size)) < 0)
{
AUDIO_SEND_TRACE("AUDIO MEMORY MANAGER: RAM RECORD WRITE FAILED", RV_TRACE_LEVEL_DEBUG_LOW);
}
}
#endif
/* recorded_size */
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: last RAM to MEMORY", record_buffer_size, RV_TRACE_LEVEL_DEBUG_LOW);
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: size recorded",
((T_AUDIO_DRIVER_LAST_NOTIFICATION *)p_message)->recorded_size, RV_TRACE_LEVEL_DEBUG_LOW);
p_session->session_info.recorded_size = ((T_AUDIO_DRIVER_LAST_NOTIFICATION *)p_message)->recorded_size;
/* stop must no longer be accepted as it is an automatic stop */
p_session->session_info.stop_req_allowed = FALSE;
/* MEM return_path */
return_path.callback_func = NULL;
return_path.addr_id = p_audio_gbl_var->addrId;
audio_driver_free_session(channel_id, return_path);
}
break;
case AUDIO_DRIVER_STATUS_MSG:
{
/* STOP OK for play */
/* FREE OK for record */
if ( ( (((T_AUDIO_DRIVER_STATUS *)p_message)->status_type == AUDIO_STOP_STATUS) &&
(((T_AUDIO_DRIVER_STATUS *)p_message)->status == AUDIO_OK)) ||
( (((T_AUDIO_DRIVER_STATUS *)p_message)->status_type == AUDIO_FREE_STATUS) &&
(((T_AUDIO_DRIVER_STATUS *)p_message)->status == AUDIO_OK)) )
{
#if (AUDIO_NEW_FFS_MANAGER)
if (p_session->session_req.audio_ffs_fd != NULL)
{
if ( ffs_close(p_session->session_req.audio_ffs_fd) != EFFS_OK )
{
audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_CLOSE);
}
AUDIO_SEND_TRACE_PARAM("AUDIO MEMORY MANAGER: close FFS file for mem channel:", mem_channel_id, RV_TRACE_LEVEL_DEBUG_LOW);
}
#endif
if (((T_AUDIO_DRIVER_STATUS *)p_message)->status_type == AUDIO_FREE_STATUS)
audio_mem_send_record_status(channel_id, p_session->session_info.recorded_size, return_path);
else
audio_mem_send_status(AUDIO_OK, channel_id, AUDIO_STOP_STATUS, return_path);
p_session->session_info.state = AUDIO_MEM_IDLE;
}
} //case AUDIO_DRIVER_STATUS_MSG:
break;
case AUDIO_MEM_STOP_REQ:
{
/* check stop req is allowed i.e. no previous stop req, nor automatic stop */
if (p_session->session_info.stop_req_allowed == TRUE)
{
p_session->session_info.stop_req_allowed = FALSE;
audio_driver_stop_session(channel_id);
}
else
{
audio_mem_error_trace(AUDIO_ERROR_STOP_EVENT);
//audio_mem_send_status(AUDIO_ERROR, channel_id, AUDIO_STOP_STATUS, return_path);
}
}
break;
case AUDIO_MEM_START_REQ:
audio_mem_error_trace(AUDIO_ERROR_START_EVENT);
//audio_mem_send_status(AUDIO_ERROR, channel_id, AUDIO_START_STATUS, return_path);
break;
}//switch (p_message->msg_id)
} //case AUDIO_MEM_WAIT_NOTIFICATION_OR_STOP:
break;
} // switch(state)
}
UINT8 audio_mem_message_switch(T_RV_HDR *p_message)
{
UINT8 channel_id;
UINT8 mem_channel_id = 0;
/* MEM START and STOP */
if ((p_message->msg_id == AUDIO_MEM_START_REQ)||
(p_message->msg_id == AUDIO_MEM_STOP_REQ))
return 1;
/* For other messages, we must check channel_id is really handled by MEM
and not by other managers such as streaming or UART */
if (p_message->msg_id == AUDIO_DRIVER_STATUS_MSG)
channel_id = ((T_AUDIO_DRIVER_STATUS *)p_message)->channel_id;
if (p_message->msg_id == AUDIO_DRIVER_NOTIFICATION_MSG)
channel_id = ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id;
if (p_message->msg_id == AUDIO_DRIVER_LAST_NOTIFICATION_MSG)
channel_id = ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id;
/* find active MEM session handling channel_id */
while ( (mem_channel_id < AUDIO_MEM_MAX_CHANNEL) &&
((p_audio_gbl_var->audio_mem_session[mem_channel_id].session_info.state == AUDIO_MEM_IDLE)||
(p_audio_gbl_var->audio_mem_session[mem_channel_id].session_req.channel_id != channel_id)))
{
mem_channel_id++;
}
if (mem_channel_id == AUDIO_MEM_MAX_CHANNEL)
return 0;
else
return 1;
}
#endif // AUDIO_MEM_MANAGER
#endif /* RVM_AUDIO_MAIN_SWE */