FreeCalypso > hg > fc-magnetite
diff src/cs/services/Audio/audio_driver.c @ 0:945cf7f506b2
src/cs: chipsetsw import from tcs211-fcmodem
binary blobs and LCD demo files have been excluded,
all line endings are LF only
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Sep 2016 22:50:11 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/services/Audio/audio_driver.c Sun Sep 25 22:50:11 2016 +0000 @@ -0,0 +1,810 @@ +/****************************************************************************/ +/* */ +/* File Name: audio_driver.c */ +/* */ +/* Purpose: This file contains all the functions used to manage the */ +/* driver. */ +/* */ +/* Version 0.1 */ +/* */ +/* Date Modification */ +/* ------------------------------------ */ +/* 09 December 2002 Create */ +/* */ +/* Author Frederic Turgis */ +/* */ +/* (C) Copyright 2002 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 "rvf/rvf_api.h" + #include "rv/rv_general.h" + #include "rvm/rvm_gen.h" + #include "audio/audio_features_i.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" + + #ifndef _WINDOWS + // include the usefull L1 header + #define BOOL_FLAG + #define CHAR_FLAG + #include "l1_types.h" + #include "cust_os.h" + #include "l1audio_cust.h" + #include "l1audio_msgty.h" + #include "l1audio_signa.h" + #include "l1_signa.h" + #else + // include the usefull L1 header + #define BOOL_FLAG + #define CHAR_FLAG + #include "l1_types.h" + #include "l1audio_const.h" + #include "l1audio_cust.h" + #include "l1audio_defty.h" + #include "l1audio_msgty.h" + #include "l1audio_signa.h" + #include "l1_const.h" + #include "l1_defty.h" + #include "l1_msgty.h" + #include "l1_signa.h" + #include "l1_varex.h" + #include "audio/tests/audio_test.h" + #endif + +#if (L1_AUDIO_DRIVER) + #if (L1_VOICE_MEMO_AMR) + extern T_AUDIO_RET audio_driver_vm_amr_play_manager (T_RV_HDR *p_message, T_AUDIO_DRIVER_SESSION *p_session); + extern T_AUDIO_RET audio_driver_vm_amr_record_manager (T_RV_HDR *p_message, T_AUDIO_DRIVER_SESSION *p_session); + extern T_AUDIO_RET audio_driver_midi_manager (T_RV_HDR *p_message, T_AUDIO_DRIVER_SESSION *p_session); + #endif + + UINT8 audio_driver_message_switch(T_RV_HDR *p_message); + void audio_driver_send_status (T_AUDIO_RET status, + UINT8 status_type, + UINT8 channel_id, + T_RV_RETURN return_path); + void audio_driver_init_send_status (T_AUDIO_RET status, + UINT8 session_id, + UINT8 channel_id, + T_RV_RETURN return_path); + void audio_driver_manager(T_RV_HDR *p_message); + T_AUDIO_RET audio_driver_get_play_buffer(UINT8 channel_id, UINT8 **pp_buffer); + T_AUDIO_RET audio_driver_play_buffer(UINT8 channel_id, UINT8 *p_buffer); + + UINT8 audio_driver_message_switch(T_RV_HDR *p_message) + { + switch (p_message->msg_id) + { + case AUDIO_DRIVER_START_SESSION: + case AUDIO_DRIVER_STOP_SESSION: + case AUDIO_DRIVER_FREE_SESSION: + return(AUDIO_DRIVER_SWITCH); + break; + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + case MMI_VM_AMR_RECORD_START_CON: + case MMI_VM_AMR_RECORD_STOP_CON: + return(AUDIO_DRIVER_VM_AMR_RECORD_SESSION_SWITCH); + break; + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + case MMI_VM_AMR_PLAY_START_CON: + case MMI_VM_AMR_PLAY_STOP_CON: + return(AUDIO_DRIVER_VM_AMR_PLAY_SESSION_SWITCH); + break; + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + case MMI_MIDI_START_CON: + case MMI_MIDI_STOP_CON: + return(AUDIO_DRIVER_MIDI_SESSION_SWITCH); + break; + #endif + default: + return(AUDIO_DRIVER_NONE); + break; + } // switch + } + + void audio_driver_send_status (T_AUDIO_RET status, + UINT8 status_type, + UINT8 channel_id, + T_RV_RETURN return_path) + { + T_AUDIO_DRIVER_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_DRIVER_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_driver_error_trace(AUDIO_ENTITY_NO_MEMORY); + rvf_delay(RVF_MS_TO_TICKS(1000)); + } + } + + // fill the header of the message + parameters + p_send_message->os_hdr.msg_id = AUDIO_DRIVER_STATUS_MSG; + p_send_message->status = status; + p_send_message->status_type = status_type; + p_send_message->channel_id = channel_id; + + // 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_driver_init_send_status (T_AUDIO_RET status, + UINT8 session_id, + UINT8 channel_id, + T_RV_RETURN return_path) + { + T_AUDIO_DRIVER_INIT_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_DRIVER_INIT_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_driver_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_DRIVER_INIT_STATUS_MSG; + + // fill the status parameters + p_send_message->status = status; + p_send_message->session_id = session_id; + p_send_message->channel_id = channel_id; + + // 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_driver_manager(T_RV_HDR *p_message) + { + T_AUDIO_DRIVER_SESSION *p_session; + T_AUDIO_DRIVER_PARAMETER *driver_parameter; + T_RV_RETURN return_path; + T_RVF_MB_STATUS mb_status; + UINT8 session_id, channel_id, state, j; + + // initialize return_path to default values + return_path.callback_func=NULL; + return_path.addr_id=0; + + // find state + extract information:channel_id or session_id + driver_parameter + switch (p_message->msg_id) + { + // start/stop session messages have channel_id so we know the driver_session + case AUDIO_DRIVER_START_SESSION: + case AUDIO_DRIVER_STOP_SESSION: + case AUDIO_DRIVER_FREE_SESSION: + channel_id = ((T_AUDIO_DRIVER_HANDLE_SESSION *)p_message)->channel_id; + p_session = &(p_audio_gbl_var->audio_driver_session[channel_id]); + state = p_session->session_info.state; + if (p_message->msg_id != AUDIO_DRIVER_STOP_SESSION) + return_path = ((T_AUDIO_DRIVER_HANDLE_SESSION *)p_message)->return_path; + else + return_path = p_session->session_req.return_path; + break; + // messages which contain only session_id, must look for it in ACTIVE driver_session + default: + { + switch (p_message->msg_id) + { + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + session_id = AUDIO_VM_AMR_RECORD_SESSION_ID; + driver_parameter = &(((T_AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION *)p_message)->driver_parameter); + return_path = ((T_AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION *)p_message)->return_path; + break; + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + session_id = AUDIO_VM_AMR_PLAY_SESSION_ID; + driver_parameter = & (((T_AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION *)p_message)->driver_parameter); + return_path = ((T_AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION *)p_message)->return_path; + break; + case MMI_VM_AMR_RECORD_START_CON: + case MMI_VM_AMR_RECORD_STOP_CON: + session_id = AUDIO_VM_AMR_RECORD_SESSION_ID; + break; + case MMI_VM_AMR_PLAY_START_CON: + case MMI_VM_AMR_PLAY_STOP_CON: + session_id = AUDIO_VM_AMR_PLAY_SESSION_ID; + break; + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + session_id = AUDIO_MIDI_SESSION_ID; + driver_parameter = &(((T_AUDIO_DRIVER_INIT_MIDI_SESSION *)p_message)->driver_parameter); + return_path = ((T_AUDIO_DRIVER_INIT_MIDI_SESSION *)p_message)->return_path; + break; + case MMI_MIDI_START_CON: + case MMI_MIDI_STOP_CON: + session_id = AUDIO_MIDI_SESSION_ID; + break; + #endif + } + + // initialize channel_id to browse all driver channels + channel_id = 0; + state = AUDIO_DRIVER_CHANNEL_WAIT_INIT; + + // look for an active session, which session_id matches the one from the message + while ( (channel_id < AUDIO_DRIVER_MAX_CHANNEL)&& + ((p_audio_gbl_var->audio_driver_session[channel_id].session_info.state == AUDIO_DRIVER_CHANNEL_WAIT_INIT)|| + (p_audio_gbl_var->audio_driver_session[channel_id].session_req.session_id != session_id)) ) + { + channel_id++; + } + // if channel_id < MAX_CHANNEL, we found an active channel so we can derive channel_id + state + if (channel_id < AUDIO_DRIVER_MAX_CHANNEL) + { + p_session = &(p_audio_gbl_var->audio_driver_session[channel_id]); + state = p_session->session_info.state; + return_path = p_session->session_req.return_path; + } + } + break; // default + } + + switch (state) + { + case AUDIO_DRIVER_CHANNEL_WAIT_INIT: + { + switch (p_message->msg_id) + { + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + #endif + { + T_AUDIO_RET result; + + // Find a free channel + channel_id = 0; + while ( (p_audio_gbl_var->audio_driver_session[channel_id].session_info.state != AUDIO_DRIVER_CHANNEL_WAIT_INIT) && + (channel_id < AUDIO_DRIVER_MAX_CHANNEL) ) + channel_id++; + + if (channel_id == AUDIO_DRIVER_MAX_CHANNEL) + { + AUDIO_SEND_TRACE("no driver channel available", RV_TRACE_LEVEL_DEBUG_LOW); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + return; + } + + AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER: open channel", channel_id, RV_TRACE_LEVEL_DEBUG_LOW); + + // get session descriptor and fill REQ parameters + p_session = &(p_audio_gbl_var->audio_driver_session[channel_id]); + p_session->session_req.session_id = session_id; + p_session->session_req.size = driver_parameter->buffer_size << 1;// we request 16-bit words buffers + p_session->session_req.nb_buffer = driver_parameter->nb_buffer; + // fill return_path parameters, may be used if next message is STOP_SESSION + p_session->session_req.return_path.callback_func = return_path.callback_func; + p_session->session_req.return_path.addr_id = return_path.addr_id; + + /************************************************************/ + /* the driver must allocate the RAM buffers pointer */ + /************************************************************/ + mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal, + sizeof(T_AUDIO_DRIVER_BUFFER_INFO)*p_session->session_req.nb_buffer, + (T_RVF_BUFFER **) (&p_session->session_info.buffer)); + + // If insufficient resources, then report a memory error and abort. + if (mb_status == RVF_RED) + { + audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + return; + } + + /************************************************************/ + /* the driver must allocate the RAM buffers */ + /************************************************************/ + for (j = 0; j < p_session->session_req.nb_buffer; 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) + { + UINT8 i; + // free already allocated buffers + buffer pointer + if (j > 0) + { + for (i = j - 1; i >= 0; i--) + rvf_free_buf((T_RVF_BUFFER *)p_session->session_info.buffer[i].p_start_pointer); + } + rvf_free_buf((T_RVF_BUFFER *)p_session->session_info.buffer); + audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + return; + } + + // initialize parameters + p_session->session_info.buffer[j].size = p_session->session_req.size; + + AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER: allocate buffer", + p_session->session_info.buffer[j].p_start_pointer, RV_TRACE_LEVEL_DEBUG_LOW); + } + + // info parameters (state must be changed before driver specific functions call + p_session->session_info.index_l1 = 0; + p_session->session_info.index_appli = 0; + p_session->session_info.stop_request = 0; + + // conversion of parameters + prepare l1 start message + switch(p_message->msg_id) + { + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + result=audio_driver_vm_amr_record_manager(p_message,p_session); + break; + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + result=audio_driver_vm_amr_play_manager(p_message,p_session); + break; + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + result=audio_driver_midi_manager(p_message,p_session); + break; + #endif + } + + // check L1 msg allocation was successfull + if (result != AUDIO_OK) + { + AUDIO_SEND_TRACE("AUDIO DRIVER MANAGER: L1 msg allocation failed", RV_TRACE_LEVEL_DEBUG_LOW); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + return; + } + + // state (must be changed after driver specific functions calls) + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_START; + + audio_driver_init_send_status(AUDIO_OK, session_id, channel_id, return_path); + } //case AUDIO_DRIVER_INIT_..._SESSION: + break; + case AUDIO_DRIVER_START_SESSION: + audio_driver_error_trace(AUDIO_ERROR_START_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_START_STATUS, channel_id, return_path); + break; + case AUDIO_DRIVER_STOP_SESSION: + audio_driver_error_trace(AUDIO_ERROR_STOP_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_STOP_STATUS, channel_id, return_path); + break; + case AUDIO_DRIVER_FREE_SESSION: + audio_driver_error_trace(AUDIO_ERROR_FREE_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_FREE_STATUS, channel_id, return_path); + break; + } // switch (p_message->msg_id) + } //case AUDIO_DRIVER_CHANNEL_WAIT_INIT: + break; + case AUDIO_DRIVER_CHANNEL_WAIT_START: + { + switch (p_message->msg_id) + { + case AUDIO_DRIVER_START_SESSION: + { + T_AUDIO_RET result; + + // fill notification parameters + p_session->session_req.return_path.callback_func = return_path.callback_func; + p_session->session_req.return_path.addr_id = return_path.addr_id; + + // send l1 message + switch(p_session->session_req.session_id) + { + #if (L1_VOICE_MEMO_AMR) + case AUDIO_VM_AMR_RECORD_SESSION_ID: + result=audio_driver_vm_amr_record_manager(p_message,p_session); + break; + case AUDIO_VM_AMR_PLAY_SESSION_ID: + result=audio_driver_vm_amr_play_manager(p_message,p_session); + break; + #endif + #if (L1_MIDI == 1) + case AUDIO_MIDI_SESSION_ID: + result=audio_driver_midi_manager(p_message,p_session); + break; + #endif + } + + if (result != AUDIO_OK) + { + audio_driver_error_trace(AUDIO_ERROR_L1_START_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_START_STATUS, channel_id, return_path); + return; + } + + // change state + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_START_CON; + } + break; + case AUDIO_DRIVER_STOP_SESSION: + { + // deallocate buffers + for(j=0; j<p_session->session_req.nb_buffer; j++) + { + mb_status=rvf_free_buf((T_RVF_BUFFER *)(p_session->session_info.buffer[j].p_start_pointer)); + + AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER MANAGER: deallocate buffer", + j, RV_TRACE_LEVEL_DEBUG_LOW); + + if (mb_status != RVF_GREEN) + AUDIO_SEND_TRACE_PARAM("can't deallocate buffer", j, RV_TRACE_LEVEL_ERROR); + } + + // Deallocate buffers pointer + rvf_free_buf((T_RVF_BUFFER *)p_session->session_info.buffer); + + // deallocate l1 message + audio_deallocate_l1_message(p_session->session_req.p_l1_send_message); + + // send status OK + audio_driver_send_status(AUDIO_OK,AUDIO_STOP_STATUS,channel_id,return_path); + + // change state + p_session->session_info.state=AUDIO_DRIVER_CHANNEL_WAIT_INIT; + } + break; + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + #endif + audio_driver_error_trace(AUDIO_ERROR_INIT_EVENT); + audio_driver_init_send_status(AUDIO_ERROR, session_id, 0, return_path); + break; + case AUDIO_DRIVER_FREE_SESSION: + audio_driver_error_trace(AUDIO_ERROR_FREE_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_FREE_STATUS, channel_id, return_path); + break; + } // switch + } //case AUDIO_DRIVER_CHANNEL_WAIT_START: + break; + case AUDIO_DRIVER_CHANNEL_WAIT_START_CON: + { + switch (p_message->msg_id) + { + #if (L1_VOICE_MEMO_AMR) + case MMI_VM_AMR_RECORD_START_CON: + case MMI_VM_AMR_PLAY_START_CON: + #endif + #if (L1_MIDI == 1) + case MMI_MIDI_START_CON: + #endif + // change state + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_STOP; + break; + case AUDIO_DRIVER_STOP_SESSION: + // change state + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_START_CON_TO_STOP; + break; + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + #endif + audio_driver_error_trace(AUDIO_ERROR_INIT_EVENT); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + break; + case AUDIO_DRIVER_START_SESSION: + audio_driver_error_trace(AUDIO_ERROR_START_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_START_STATUS, channel_id, return_path); + break; + case AUDIO_DRIVER_FREE_SESSION: + audio_driver_error_trace(AUDIO_ERROR_FREE_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_FREE_STATUS, channel_id, return_path); + break; + } // switch + } //case AUDIO_DRIVER_CHANNEL_WAIT_START_CON: + break; + case AUDIO_DRIVER_CHANNEL_WAIT_STOP: + { + switch (p_message->msg_id) + { + case AUDIO_DRIVER_STOP_SESSION: + { + // 1st stop request + if (p_session->session_info.stop_request == 0) + { + T_AUDIO_RET result; + + // send l1 message STOP_REQ + switch(p_session->session_req.session_id) + { + #if (L1_VOICE_MEMO_AMR) + case AUDIO_VM_AMR_RECORD_SESSION_ID: + result=audio_driver_vm_amr_record_manager(p_message,p_session); + break; + case AUDIO_VM_AMR_PLAY_SESSION_ID: + result=audio_driver_vm_amr_play_manager(p_message,p_session); + break; + #endif + #if (L1_MIDI == 1) + case AUDIO_MIDI_SESSION_ID: + result=audio_driver_midi_manager(p_message,p_session); + break; + #endif + } + + // allocate or send L1 msg went wrong + if (result != AUDIO_OK) + { + audio_driver_error_trace(AUDIO_ERROR_L1_STOP_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_STOP_STATUS, channel_id, return_path); + return; + } + + // STOP has been requested, no longer accept it + p_session->session_info.stop_request = 1; + } + else + { + audio_driver_error_trace(AUDIO_ERROR_STOP_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_STOP_STATUS, channel_id, return_path); + } + } + break; + #if (L1_VOICE_MEMO_AMR) + case MMI_VM_AMR_RECORD_STOP_CON: + { + // send last notification + T_AUDIO_DRIVER_LAST_NOTIFICATION *p_status_message; + + // Allocate the Riviera buffer + mb_status = RVF_RED; + while (mb_status == RVF_RED) + { + mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal, + sizeof (T_AUDIO_DRIVER_LAST_NOTIFICATION), + (T_RVF_BUFFER **) (&p_status_message)); + // If insufficient resources, then report a memory error and abort. + if (mb_status == RVF_RED) + { + // the memory is insufficient to continue the non regression test + audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY); + rvf_delay(RVF_MS_TO_TICKS(1000)); + } + } + + // Fill the message ID + p_status_message->header.msg_id = AUDIO_DRIVER_LAST_NOTIFICATION_MSG; + + // fill parameters + p_status_message->channel_id = channel_id; + p_status_message->recorded_size = ((T_MMI_VM_AMR_RECORD_CON *)p_message)->recorded_size - SC_VM_AMR_END_MASK_SIZE; + p_status_message->p_buffer = + (UINT16 *)p_session->session_info.buffer[p_session->session_info.index_l1].p_start_pointer; + + if (return_path.callback_func == NULL) + rvf_send_msg (return_path.addr_id, p_status_message); + else + { + // call the callback function + (*(return_path.callback_func))((void *)(p_status_message)); + rvf_free_buf((T_RVF_BUFFER *)p_status_message); + } + + // change state + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_FREE; + } + break; + #endif // #if (L1_VOICE_MEMO_AMR) + #if (L1_VOICE_MEMO_AMR) + case MMI_VM_AMR_PLAY_STOP_CON: + #endif + #if (L1_MIDI == 1) + case MMI_MIDI_STOP_CON: + #endif + { + // deallocate buffers + for (j = 0; j < p_session->session_req.nb_buffer; j++) + { + mb_status = rvf_free_buf ((T_RVF_BUFFER *) (p_session->session_info.buffer[j].p_start_pointer)); + + AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER MANAGER: deallocate buffer", j, RV_TRACE_LEVEL_DEBUG_LOW); + + if (mb_status != RVF_GREEN) + AUDIO_SEND_TRACE_PARAM("can't deallocate buffer", j, RV_TRACE_LEVEL_ERROR); + } + // Deallocate buffers pointer + rvf_free_buf((T_RVF_BUFFER *)p_session->session_info.buffer); + + audio_driver_send_status (AUDIO_OK, AUDIO_STOP_STATUS, channel_id, + return_path); + // change state + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_INIT; + } + break; + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + #endif + audio_driver_error_trace(AUDIO_ERROR_INIT_EVENT); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + break; + case AUDIO_DRIVER_START_SESSION: + audio_driver_error_trace(AUDIO_ERROR_START_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_START_STATUS, channel_id, return_path); + break; + case AUDIO_DRIVER_FREE_SESSION: + audio_driver_error_trace(AUDIO_ERROR_FREE_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_FREE_STATUS, channel_id, return_path); + break; + } //switch + } //case AUDIO_DRIVER_CHANNEL_WAIT_STOP: + break; + case AUDIO_DRIVER_CHANNEL_WAIT_START_CON_TO_STOP: + { + T_AUDIO_RET result = AUDIO_OK; + switch (p_message->msg_id) + { + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + #endif + audio_driver_error_trace(AUDIO_ERROR_INIT_EVENT); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + return; + break; + case AUDIO_DRIVER_START_SESSION: + audio_driver_error_trace(AUDIO_ERROR_START_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_START_STATUS, channel_id, return_path); + return; + break; + case AUDIO_DRIVER_STOP_SESSION: + audio_driver_error_trace(AUDIO_ERROR_STOP_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_STOP_STATUS, channel_id, return_path); + return; + break; + case AUDIO_DRIVER_FREE_SESSION: + audio_driver_error_trace(AUDIO_ERROR_FREE_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_FREE_STATUS, channel_id, return_path); + return; + break; + #if (L1_VOICE_MEMO_AMR) + case MMI_VM_AMR_RECORD_START_CON: + // send L1 stop msg + result=audio_driver_vm_amr_record_manager(p_message, p_session); + break; + case MMI_VM_AMR_PLAY_START_CON: + // send L1 stop msg + result=audio_driver_vm_amr_play_manager(p_message, p_session); + break; + #endif + #if (L1_MIDI == 1) + case MMI_MIDI_START_CON: + // send L1 stop msg + result=audio_driver_midi_manager(p_message,p_session); + break; + #endif + } + + if (result != AUDIO_OK) + { + audio_driver_send_status(AUDIO_ERROR, AUDIO_STOP_STATUS, channel_id, return_path); + return; + } + else + { + // next state should be WAIT_STOP_CON, which is WAIT_STOP + stop_request == 1 + p_session->session_info.stop_request = 1; + // change state + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_STOP; + } + } + break; + case AUDIO_DRIVER_CHANNEL_WAIT_FREE: + { + switch (p_message->msg_id) + { + case AUDIO_DRIVER_FREE_SESSION: + { + // deallocate buffers + for (j = 0; j < p_session->session_req.nb_buffer; j++) + { + mb_status = rvf_free_buf ((T_RVF_BUFFER *) (p_session->session_info.buffer[j].p_start_pointer)); + + AUDIO_SEND_TRACE_PARAM("AUDIO DRIVER MANAGER: deallocate buffer", j, RV_TRACE_LEVEL_DEBUG_LOW); + + if (mb_status != RVF_GREEN) + AUDIO_SEND_TRACE_PARAM("can't deallocate buffer", j, RV_TRACE_LEVEL_ERROR); + } + // Deallocate buffers pointer + rvf_free_buf((T_RVF_BUFFER *)p_session->session_info.buffer); + + audio_driver_send_status (AUDIO_OK, AUDIO_FREE_STATUS, channel_id, + return_path); + + // change state + p_session->session_info.state = AUDIO_DRIVER_CHANNEL_WAIT_INIT; + } + break; + #if (L1_VOICE_MEMO_AMR) + case AUDIO_DRIVER_INIT_VM_AMR_RECORD_SESSION: + case AUDIO_DRIVER_INIT_VM_AMR_PLAY_SESSION: + #endif + #if (L1_MIDI == 1) + case AUDIO_DRIVER_INIT_MIDI_SESSION: + #endif + audio_driver_error_trace(AUDIO_ERROR_INIT_EVENT); + audio_driver_init_send_status(AUDIO_ERROR, session_id, channel_id, return_path); + break; + case AUDIO_DRIVER_START_SESSION: + audio_driver_error_trace(AUDIO_ERROR_START_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_START_STATUS, channel_id, return_path); + break; + case AUDIO_DRIVER_STOP_SESSION: + audio_driver_error_trace(AUDIO_ERROR_STOP_EVENT); + audio_driver_send_status(AUDIO_ERROR, AUDIO_STOP_STATUS, channel_id, return_path); + break; + } // switch + } + break; + } + } +#endif // (L1_AUDIO_DRIVER) + +#endif // #ifdef RVM_AUDIO_MAIN_SWE