FreeCalypso > hg > fc-magnetite
view src/cs/services/Audio/audio_ffs.c @ 478:5e39123540e6
hybrid fw: Openmoko-mimicking AT@BAND command implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 14 Jun 2018 06:04:54 +0000 |
parents | 945cf7f506b2 |
children |
line wrap: on
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 */