FreeCalypso > hg > fc-magnetite
view src/cs/services/Audio/audio_midi.c @ 516:1ed9de6c90bd
src/g23m-gsm/sms/sms_for.c: bogus malloc removed
The new error handling code that was not present in TCS211 blob version
contains a malloc call that is bogus for 3 reasons:
1) The memory allocation in question is not needed in the first place;
2) libc malloc is used instead of one of the firmware's proper ways;
3) The memory allocation is made inside a function and then never freed,
i.e., a memory leak.
This bug was caught in gcc-built FreeCalypso fw projects (Citrine
and Selenite) because our gcc environment does not allow any use of
libc malloc (any reference to malloc produces a link failure),
but this code from TCS3.2 is wrong even for Magnetite: if this code
path is executed repeatedly over a long time, the many small allocations
made by this malloc call without a subsequent free will eventually
exhaust the malloc heap provided by the TMS470 environment, malloc will
start returning NULL, and the bogus code will treat it as an error.
Because the memory allocation in question is not needed at all,
the fix entails simply removing it.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 22 Jul 2018 06:04:49 +0000 |
parents | 945cf7f506b2 |
children |
line wrap: on
line source
/****************************************************************************/ /* */ /* File Name: audio_midi.c */ /* */ /* Purpose: This file contains all the functions used to manage MIDI */ /* */ /* Version 0.1 */ /* */ /* Date Modification */ /* ------------------------------------ */ /* 11 June 2003 Create */ /* */ /* Author */ /* Fabrice Goucem */ /* */ /* (C) Copyright 2003 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 the usefull L1 header #include "l1_confg.h" #include "rv/rv_general.h" #include "rvm/rvm_gen.h" #include "audio/audio_features_i.h" #include "audio/audio_ffs_i.h" #include "audio/audio_api.h" #include "audio/audio_structs_i.h" #include "audio/audio_var_i.h" #include "audio/audio_messages_i.h" #include "rvf/rvf_target.h" #include "audio/audio_const_i.h" #include "audio/audio_error_hdlr_i.h" #include "audio/audio_macro_i.h" // include the useful L1 header #define BOOL_FLAG #define CHAR_FLAG #include "l1_types.h" #include "l1audio_cust.h" #include "l1audio_msgty.h" #include "l1audio_signa.h" /********************************************************************************/ /* */ /* Function Name: audio_midi_start */ /* */ /* Purpose: This function is called to initiate a MIDI file playback */ /* */ /* Input Parameters: */ /* Midi file parameters, */ /* Return path. */ /* */ /* Output Parameters: */ /* Validation of the MIDI parameters. */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ T_AUDIO_RET audio_midi_start(T_AUDIO_MIDI_PARAMETER *parameter, T_RV_RETURN *p_return_path) { #if (L1_MIDI==1) // Declare local variables T_RVF_MB_STATUS mb_status=RVF_GREEN; T_AUDIO_MIDI_START *p_msg_start=NULL; T_FFS_FD ffs_fd; /************************ audio_midi_start function begins ******************/ if(p_audio_gbl_var==NULL) { audio_midi_error_trace(AUDIO_ENTITY_NOT_START); return(AUDIO_ERROR); } // check if the midi file exists #ifndef _WINDOWS ffs_fd=ffs_open(parameter->midi_name,FFS_O_RDONLY); if(ffs_fd<=0) { audio_midi_error_trace(AUDIO_ENTITY_FILE_ERROR); return(AUDIO_ERROR); } #else ffs_fd=0xdeadbeef; #endif // _WINDOWS // allocate the memory for the message to send mb_status=rvf_get_buf(p_audio_gbl_var->mb_external, sizeof(T_AUDIO_MIDI_START), (T_RVF_BUFFER **)(&p_msg_start)); // If insufficient resources, then report a memory error and abort if(mb_status==RVF_YELLOW) { // deallocate the memory rvf_free_buf((T_RVF_BUFFER *)p_msg_start); audio_midi_error_trace(AUDIO_ENTITY_NO_MEMORY); #ifndef _WINDOWS ffs_close(ffs_fd); #endif return(AUDIO_ERROR); } else { if(mb_status==RVF_RED) { audio_midi_error_trace(AUDIO_ENTITY_NO_MEMORY); #ifndef _WINDOWS ffs_close(ffs_fd); #endif return (AUDIO_ERROR); } } // fill the message id p_msg_start->os_hdr.msg_id=AUDIO_MIDI_START_REQ; // fill the address source id p_msg_start->os_hdr.src_addr_id =rvf_get_taskid(); p_msg_start->os_hdr.dest_addr_id=p_audio_gbl_var->addrId; // fill the message parameters p_msg_start->audio_ffs_fd=ffs_fd; if(p_return_path->callback_func==NULL) { p_msg_start->return_path.addr_id=p_return_path->addr_id; p_msg_start->return_path.callback_func=NULL; } else p_msg_start->return_path.callback_func=p_return_path->callback_func; // send the messsage to the audio entity rvf_send_msg(p_audio_gbl_var->addrId,p_msg_start); return(AUDIO_OK); #else // L1_MIDI==1 AUDIO_SEND_TRACE("MIDI not compiled",RV_TRACE_LEVEL_DEBUG_LOW); return(AUDIO_ERROR); #endif // L1_MIDI==1 } /*********************** End of audio_midi_start function ******************/ /********************************************************************************/ /* */ /* Function Name: audio_midi_stop */ /* */ /* Purpose: This function is called to stop MIDI file playback */ /* */ /* Input Parameters: */ /* Return path. */ /* */ /* Output Parameters: */ /* None. */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ T_AUDIO_RET audio_midi_stop(void) { #if (L1_MIDI==1) // Declare local variables T_RVF_MB_STATUS mb_status =RVF_GREEN; T_AUDIO_MIDI_STOP *p_msg_stop=NULL; /************************ audio_midi_stop function begins ****************/ if(p_audio_gbl_var==NULL) { audio_midi_error_trace(AUDIO_ENTITY_NOT_START); return(AUDIO_ERROR); } // allocate the memory for the message to send mb_status=rvf_get_buf(p_audio_gbl_var->mb_external, sizeof(T_AUDIO_MIDI_STOP), (T_RVF_BUFFER **)(&p_msg_stop)); // If insufficient resources, then report a memory error and abort if(mb_status==RVF_YELLOW) { // deallocate the memory rvf_free_buf((T_RVF_BUFFER *)p_msg_stop); audio_midi_error_trace(AUDIO_ENTITY_NO_MEMORY); return(AUDIO_ERROR); } else { if(mb_status==RVF_RED) { audio_midi_error_trace(AUDIO_ENTITY_NO_MEMORY); return(AUDIO_ERROR); } } // fill the message id p_msg_stop->os_hdr.msg_id=AUDIO_MIDI_STOP_REQ; // fill the address source id p_msg_stop->os_hdr.src_addr_id =rvf_get_taskid(); p_msg_stop->os_hdr.dest_addr_id=p_audio_gbl_var->addrId; // send the messsage to the audio entity rvf_send_msg(p_audio_gbl_var->addrId,p_msg_stop); return(AUDIO_OK); #else // L1_MIDI==1 AUDIO_SEND_TRACE("MIDI not compiled",RV_TRACE_LEVEL_DEBUG_LOW); return(AUDIO_ERROR); #endif // L1_MIDI==1 } /*********************** End of audio_midi_stop function *******************/ #if (L1_MIDI == 1) /********************************************************************************/ /* */ /* Function Name: audio_midi_message_switch */ /* */ /* Purpose: Manage the message supply */ /* */ /* Input Parameters: */ /* start or stop message from midi features */ /* */ /* Output Parameters: */ /* index of the manager */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ UINT8 audio_midi_message_switch(T_RV_HDR *p_message) { switch(p_message->msg_id) { case AUDIO_MIDI_START_REQ: case AUDIO_MIDI_STOP_REQ: return(AUDIO_MIDI); break; // driver init => check session_id is MIDI case AUDIO_DRIVER_INIT_STATUS_MSG: { UINT8 session_id=((T_AUDIO_DRIVER_INIT_STATUS *)p_message)->session_id; // session_id is MIDI if((session_id==AUDIO_MIDI_SESSION_ID) && (p_audio_gbl_var->midi.state!=AUDIO_IDLE)) return(AUDIO_MIDI); else return(AUDIO_MIDI_NONE); } break; case AUDIO_DRIVER_NOTIFICATION_MSG: { UWORD8 channel_id; channel_id=((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id; if((channel_id==p_audio_gbl_var->midi.channel_id) && (p_audio_gbl_var->midi.state>AUDIO_WAIT_CHANNEL_ID)) return(AUDIO_MIDI); else return(AUDIO_MIDI_NONE); } break; case AUDIO_DRIVER_STATUS_MSG: { UWORD8 channel_id; channel_id=((T_AUDIO_DRIVER_STATUS *)p_message)->channel_id; if((channel_id==p_audio_gbl_var->midi.channel_id) && (p_audio_gbl_var->midi.state>AUDIO_WAIT_CHANNEL_ID)) return(AUDIO_MIDI); else return(AUDIO_MIDI_NONE); } break; default: return(AUDIO_MIDI_NONE); break; } // switch } /********************************************************************************/ /* */ /* Function Name: audio_midi_send_status */ /* */ /* Purpose: This function sends the MIDI play status to the entity */ /* */ /* Input Parameters: */ /* status, */ /* return path */ /* */ /* Output Parameters: */ /* None. */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ void audio_midi_send_status(T_AUDIO_RET status, T_RV_RETURN *return_path) { T_AUDIO_MIDI_STATUS *p_send_message; T_RVF_MB_STATUS mb_status=RVF_RED; // allocate the message buffer while(mb_status==RVF_RED) { mb_status=rvf_get_buf(p_audio_gbl_var->mb_external, sizeof(T_AUDIO_MIDI_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_midi_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_MIDI_STATUS_MSG; // fill the status parameters p_send_message->status=status; // 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); } } /********************************************************************************/ /* */ /* Function Name: audio_midi_manager */ /* */ /* Purpose: This function is called to manage a MIDI play manager */ /* */ /* Input Parameters: */ /* Message to the audio entity */ /* */ /* Output Parameters: */ /* None. */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ void audio_midi_manager(T_RV_HDR *p_message) { // Declare local variables T_RV_HDR *p_send_message; T_RVF_MB_STATUS mb_status; T_RV_RETURN return_path; // initialize the return path return_path.callback_func=NULL; return_path.addr_id=p_audio_gbl_var->addrId; /**************** audio_midi_manager function begins ***********************/ switch(p_audio_gbl_var->midi.state) { case AUDIO_IDLE: { switch(p_message->msg_id) { case AUDIO_MIDI_START_REQ: { T_AUDIO_DRIVER_PARAMETER driver_parameter; p_audio_gbl_var->midi.stop_req_allowed=TRUE; // save the return path + ffs_fd p_audio_gbl_var->midi.return_path.callback_func=((T_AUDIO_MIDI_START *)p_message)->return_path.callback_func; p_audio_gbl_var->midi.return_path.addr_id=((T_AUDIO_MIDI_START *)p_message)->return_path.addr_id; p_audio_gbl_var->midi.ffs_fd=((T_AUDIO_MIDI_START *)p_message)->audio_ffs_fd; // driver parameters driver_parameter.nb_buffer = AUDIO_MIDI_NB_BUFFER; driver_parameter.buffer_size = AUDIO_MIDI_SIZE; // 16 bit words // return_path for driver return_path.callback_func = NULL; return_path.addr_id = p_audio_gbl_var->addrId; // init driver audio_driver_init_midi_session(&driver_parameter,&return_path); p_audio_gbl_var->midi.state=AUDIO_WAIT_CHANNEL_ID; } break; case AUDIO_MIDI_STOP_REQ: { audio_midi_error_trace(AUDIO_ERROR_STOP_EVENT); // do not send a status message because of pre-emption issues // An automatic stop can pre-empt a stop request. A status is sent + back in state idle // then the stop request is received and another status is sent, which can be misinterpreted } break; } } break; // AUDIO_IDLE case AUDIO_WAIT_CHANNEL_ID: { switch(p_message->msg_id) { case AUDIO_DRIVER_INIT_STATUS_MSG: { UINT8 *play_buffer; INT16 size_read; // check init is successfull otherwise, send status AUDIO_ERROR if(((T_AUDIO_DRIVER_INIT_STATUS *)p_message)->status==AUDIO_OK) { // get channel id p_audio_gbl_var->midi.channel_id=((T_AUDIO_DRIVER_INIT_STATUS *)p_message)->channel_id; // initializations p_audio_gbl_var->midi.size = AUDIO_MIDI_SIZE << 1; p_audio_gbl_var->midi.stop_req_allowed=TRUE; // fill all buffers in advance while(audio_driver_get_play_buffer(p_audio_gbl_var->midi.channel_id,&play_buffer)==AUDIO_OK) { // write from FLASH to RAM buffer if(p_audio_gbl_var->midi.ffs_fd!=NULL) { #ifndef _WINDOWS size_read=ffs_read(p_audio_gbl_var->midi.ffs_fd,play_buffer,p_audio_gbl_var->midi.size); #else size_read=p_audio_gbl_var->midi.size; #endif if(size_read<EFFS_OK) { #ifndef _WINDOWS if(ffs_close(p_audio_gbl_var->midi.ffs_fd)!=EFFS_OK) audio_mem_error_trace(AUDIO_ENTITY_FILE_NO_CLOSE); #endif AUDIO_SEND_TRACE("AUDIO MIDI: FFS PLAY READ failed",RV_TRACE_LEVEL_DEBUG_LOW); audio_mem_send_status(AUDIO_ERROR,p_audio_gbl_var->midi.channel_id,AUDIO_START_STATUS,return_path); return; } } AUDIO_SEND_TRACE_PARAM("AUDIO MIDI: size read",size_read,RV_TRACE_LEVEL_DEBUG_LOW); audio_driver_play_buffer(p_audio_gbl_var->midi.channel_id,play_buffer); } // send message audio_driver_start_session(p_audio_gbl_var->midi.channel_id,return_path); // change state p_audio_gbl_var->midi.state=AUDIO_WAIT_STOP; } else { audio_midi_error_trace(AUDIO_ERROR_START_EVENT); audio_midi_send_status(AUDIO_ERROR, &p_audio_gbl_var->midi.return_path); // change state p_audio_gbl_var->midi.state=AUDIO_IDLE; } } break; case AUDIO_MIDI_STOP_REQ: // change state p_audio_gbl_var->midi.state=AUDIO_WAIT_CHANNEL_ID_TO_STOP; break; } } // case AUDIO_WAIT_CHANNEL_ID: break; case AUDIO_WAIT_STOP: { switch(p_message->msg_id) { case AUDIO_DRIVER_NOTIFICATION_MSG: { UINT8 *play_buffer; INT16 size_read; // try to get a buffer if(audio_driver_get_play_buffer(p_audio_gbl_var->midi.channel_id,&play_buffer)==AUDIO_OK) { #ifndef _WINDOWS size_read=ffs_read(p_audio_gbl_var->midi.ffs_fd,play_buffer,p_audio_gbl_var->midi.size); #else size_read=p_audio_gbl_var->midi.size; #endif if(size_read<EFFS_OK) { AUDIO_SEND_TRACE("AUDIO MIDI: FFS PLAY READ FILED",RV_TRACE_LEVEL_DEBUG_LOW); size_read=0; // will put END_MASK in whole buffer so stops play } audio_driver_play_buffer(p_audio_gbl_var->midi.channel_id,play_buffer); if(size_read>0) AUDIO_SEND_TRACE_PARAM("AUDIO MIDI: size read",size_read,RV_TRACE_LEVEL_DEBUG_LOW); else AUDIO_SEND_TRACE("AUDIO MIDI: buffer not used",RV_TRACE_LEVEL_DEBUG_LOW); } // if(audio_driver_get_play_buffer(channel_id,&p_buffer)==AUDIO_OK) else AUDIO_SEND_TRACE("AUDIO MIDI: no buffer available",RV_TRACE_LEVEL_DEBUG_LOW); } break; // case AUDIO_DRIVER_NOTIFICATION_MSG case AUDIO_MIDI_STOP_REQ: if(p_audio_gbl_var->midi.stop_req_allowed==TRUE) { p_audio_gbl_var->midi.stop_req_allowed=FALSE; audio_driver_stop_session(p_audio_gbl_var->midi.channel_id); } else AUDIO_SEND_TRACE("AUDIO MIDI: second stop request received",RV_TRACE_LEVEL_WARNING); break; case AUDIO_DRIVER_STATUS_MSG: if(p_audio_gbl_var->midi.ffs_fd!=NULL) { #ifndef _WINDOWS if(ffs_close(p_audio_gbl_var->midi.ffs_fd)!=EFFS_OK) audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_CLOSE); #endif AUDIO_SEND_TRACE("AUDIO MIDI: close FFS file", RV_TRACE_LEVEL_DEBUG_LOW); } audio_midi_send_status(AUDIO_OK,&p_audio_gbl_var->midi.return_path); p_audio_gbl_var->midi.state=AUDIO_IDLE; break; } } break; // WAIT_STOP case AUDIO_WAIT_CHANNEL_ID_TO_STOP: { switch(p_message->msg_id) { case AUDIO_DRIVER_INIT_STATUS_MSG: { if(((T_AUDIO_DRIVER_INIT_STATUS *)p_message)->status==AUDIO_OK) { // get channel_id p_audio_gbl_var->midi.channel_id=((T_AUDIO_DRIVER_INIT_STATUS *)p_message)->channel_id; audio_driver_stop_session(p_audio_gbl_var->midi.channel_id); // change state p_audio_gbl_var->midi.state=AUDIO_WAIT_DRIVER_STOP_CON; } else { // close file if(p_audio_gbl_var->midi.ffs_fd!=NULL) { #ifndef _WINDOWS if(ffs_close(p_audio_gbl_var->midi.ffs_fd)!=EFFS_OK) audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_CLOSE); #endif AUDIO_SEND_TRACE("AUDIO MIDI: close FFS file:",RV_TRACE_LEVEL_DEBUG_LOW); } audio_midi_send_status(AUDIO_OK,&p_audio_gbl_var->midi.return_path); // change state p_audio_gbl_var->midi.state=AUDIO_IDLE; } } break; case AUDIO_MIDI_STOP_REQ: audio_midi_error_trace(AUDIO_ERROR_STOP_EVENT); break; } } // case AUDIO_WAIT_CHANNEL_ID_TO_STOP: break; case AUDIO_WAIT_DRIVER_STOP_CON: { switch(p_message->msg_id) { case AUDIO_DRIVER_STATUS_MSG: { if(((T_AUDIO_DRIVER_STATUS *)p_message)->status_type==AUDIO_STOP_STATUS) { // close file if(p_audio_gbl_var->midi.ffs_fd!=NULL) { #ifndef _WINDOWS if(ffs_close(p_audio_gbl_var->midi.ffs_fd)!=EFFS_OK) audio_ffs_error_trace(AUDIO_ENTITY_FILE_NO_CLOSE); #endif AUDIO_SEND_TRACE("AUDIO MIDI: close FFS file",RV_TRACE_LEVEL_DEBUG_LOW); } audio_midi_send_status(((T_AUDIO_DRIVER_STATUS *)p_message)->status, &p_audio_gbl_var->midi.return_path); p_audio_gbl_var->midi.state=AUDIO_IDLE; } } break; case AUDIO_MIDI_STOP_REQ: audio_midi_error_trace(AUDIO_ERROR_STOP_EVENT); break; } } //case AUDIO_WAIT_DRIVER_STOP_CON: break; } } /*********************** End of audio_midi_manager function **********************/ /********************************************************************************/ /* */ /* Function Name: audio_driver_midi_manager */ /* */ /* Purpose: This function is called to manage a MIDI manager */ /* */ /* Input Parameters: */ /* Message to the audio entity */ /* */ /* Output Parameters: */ /* None. */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ T_AUDIO_RET audio_driver_midi_manager(T_RV_HDR *p_message, T_AUDIO_DRIVER_SESSION *p_session) { /**************** audio_driver_midi_manager function begins ***********************/ switch(p_session->session_info.state) { case AUDIO_DRIVER_CHANNEL_WAIT_INIT: // init buffer index, layer1 not valid until 1st buffer is filled // index_l1 will be set to 0 when get_play_buffer() is called in WAIT_START state p_session->session_info.index_l1 = 0xFF; p_session->session_info.index_appli = 0; p_session->session_info.play_api_state = AUDIO_PLAY_API_STATE_GET_BUF; // allocate the buffer for the message to the L1 p_session->session_req.p_l1_send_message=audio_allocate_l1_message(sizeof(T_MMI_MIDI_REQ)); ((T_MMI_MIDI_REQ *)(p_session->session_req.p_l1_send_message))->session_id=AUDIO_MIDI_SESSION_ID; if(p_session->session_req.p_l1_send_message!=NULL) return(AUDIO_OK); else return(AUDIO_ERROR); break; case AUDIO_DRIVER_CHANNEL_WAIT_START: // send the start midi message to the L1 audio_send_l1_message(MMI_MIDI_START_REQ,p_session->session_req.p_l1_send_message); return(AUDIO_OK); break; case AUDIO_DRIVER_CHANNEL_WAIT_STOP: { // send the stop command to the audio L1 void *p_send_message=audio_allocate_l1_message(0); if(p_send_message!=NULL) { // send the stop command to the audio L1 audio_send_l1_message(MMI_MIDI_STOP_REQ,p_send_message); return(AUDIO_OK); } return(AUDIO_ERROR); } break; case AUDIO_DRIVER_CHANNEL_WAIT_START_CON_TO_STOP: { // send the stop command to the audio L1 void *p_send_message=audio_allocate_l1_message(0); if(p_send_message!=NULL) { // send the stop command to the audio L1 audio_send_l1_message(MMI_MIDI_STOP_REQ,p_send_message); return(AUDIO_OK); } return(AUDIO_ERROR); } break; } } /*********************** End of audio_driver_midi_manager function **********************/ /********************************************************************************/ /* */ /* Function Name: audio_driver_init_midi_session */ /* */ /* Purpose: This function is called in order to initialize MIDI */ /* */ /* Input Parameters: */ /* Specific MIDI parameters */ /* Driver parameters */ /* Return path */ /* */ /* Output Parameters: */ /* Validation of the parameters */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ T_AUDIO_RET audio_driver_init_midi_session(T_AUDIO_DRIVER_PARAMETER *p_driver_parameter, T_RV_RETURN *p_return_path) { #if (L1_MIDI==1) /* Declare local variables. */ T_RVF_MB_STATUS mb_status = RVF_GREEN; T_AUDIO_DRIVER_INIT_MIDI_SESSION *p_msg = NULL; /************************ audio_keybeep_stop function begins ****************/ if (p_audio_gbl_var == NULL ) { audio_driver_error_trace(AUDIO_ENTITY_NOT_START); return(AUDIO_ERROR); } /* If bad parameters report an error and abort.*/ if(p_driver_parameter->nb_buffer<2) { audio_driver_error_trace(AUDIO_ENTITY_BAD_PARAMETER); return (AUDIO_ERROR); } /* allocate the memory for the message to send */ mb_status = rvf_get_buf (p_audio_gbl_var->mb_internal, sizeof (T_AUDIO_DRIVER_INIT_MIDI_SESSION), (T_RVF_BUFFER **) (&p_msg)); /* If insufficient resources, then report a memory error and abort. */ if (mb_status == RVF_YELLOW) { /* deallocate the memory */ rvf_free_buf((T_RVF_BUFFER *)p_msg); audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY); return (AUDIO_ERROR); } else if (mb_status == RVF_RED) { audio_driver_error_trace(AUDIO_ENTITY_NO_MEMORY); return (AUDIO_ERROR); } /* fill the message id */ p_msg->os_hdr.msg_id = AUDIO_DRIVER_INIT_MIDI_SESSION; p_msg->os_hdr.dest_addr_id = p_audio_gbl_var->addrId; /* fill parameters */ p_msg->driver_parameter.buffer_size = p_driver_parameter->buffer_size; p_msg->driver_parameter.nb_buffer = p_driver_parameter->nb_buffer; if (p_return_path->callback_func == NULL) { p_msg->return_path.addr_id = p_return_path->addr_id; p_msg->return_path.callback_func = NULL; } else p_msg->return_path.callback_func = p_return_path->callback_func; /* send the messsage to the audio entity */ rvf_send_msg (p_audio_gbl_var->addrId, p_msg); return (AUDIO_OK); #else // L1_MIDI==1 AUDIO_SEND_TRACE("MIDI not compiled", RV_TRACE_LEVEL_DEBUG_LOW); return (AUDIO_ERROR); #endif // L1_MIDI==1 } /********************************************************************************/ /* */ /* Function Name: audio_midi_l1_simulator */ /* */ /* Purpose: This function simulates the L1 for MIDI */ /* */ /* Input Parameters: */ /* event: Event that triggered the function */ /* p_msg: Message (if any) associated with the event */ /* */ /* Note: */ /* None. */ /* */ /* Revision History: */ /* None. */ /* */ /********************************************************************************/ void audio_midi_l1_simulator(UINT16 event, T_RV_HDR *p_message) { #ifdef _WINDOWS enum { WAIT_START_REQ, WAIT_STOP }; T_RVF_MB_STATUS mb_status; T_RV_RETURN *return_path=&(p_audio_gbl_var->audio_driver_session[p_audio_gbl_var->midi.channel_id].session_req.return_path); switch(p_audio_gbl_var->midi.l1_state) { case WAIT_START_REQ: if(p_message->msg_id==MMI_MIDI_START_REQ) { rvf_start_timer(AUDIO_MIDI_L1_SIMUL_TIMER, RVF_MS_TO_TICKS(1000), AUDIO_MIDI_L1_SIMUL_ONE_SHOT_TIMER); p_audio_gbl_var->midi.counter=10; // send MMI_MIDI_START_CON message to the Riviera audio entity mb_status=rvf_get_buf(p_audio_gbl_var->mb_internal, sizeof(T_AUDIO_DRIVER_NOTIFICATION), (T_RVF_BUFFER **)(&p_message)); if(mb_status==RVF_RED) { AUDIO_SEND_TRACE("AUDIO entity has no memory for driver notification",RV_TRACE_LEVEL_ERROR); return; } ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->header.msg_id=MMI_MIDI_START_CON; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id=p_audio_gbl_var->midi.channel_id; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer=NULL; if(return_path->callback_func==NULL) rvf_send_msg(return_path->addr_id, p_message); else { (*return_path->callback_func)((void *)(p_message)); rvf_free_buf((T_RVF_BUFFER *)p_message); } p_audio_gbl_var->midi.l1_state=WAIT_STOP; return; } break; case WAIT_STOP: if(event & AUDIO_MIDI_L1_SIMUL_TIMER_EVT_MASK) { p_audio_gbl_var->midi.counter--; // switch buffer { T_AUDIO_DRIVER_SESSION *p=&p_audio_gbl_var->audio_driver_session[p_audio_gbl_var->midi.channel_id]; p->session_info.index_l1++; if(p->session_info.index_l1==p->session_req.nb_buffer) p->session_info.index_l1=0; } // send notification message to the Riviera audio entity mb_status=rvf_get_buf(p_audio_gbl_var->mb_internal, sizeof(T_AUDIO_DRIVER_NOTIFICATION), (T_RVF_BUFFER **)(&p_message)); if(mb_status==RVF_RED) { AUDIO_SEND_TRACE("AUDIO entity has no memory for driver notification",RV_TRACE_LEVEL_ERROR); return; } ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->header.msg_id=AUDIO_DRIVER_NOTIFICATION_MSG; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id=p_audio_gbl_var->midi.channel_id; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer=NULL; if(return_path->callback_func==NULL) rvf_send_msg(return_path->addr_id, p_message); else { (*return_path->callback_func)((void *)(p_message)); rvf_free_buf((T_RVF_BUFFER *)p_message); } // check if we're done with the simulation if(p_audio_gbl_var->midi.counter==0) { rvf_stop_timer(AUDIO_MIDI_L1_SIMUL_TIMER); // send MMI_MIDI_STOP_CON message to the Riviera audio entity mb_status=rvf_get_buf(p_audio_gbl_var->mb_internal, sizeof(T_AUDIO_DRIVER_NOTIFICATION), (T_RVF_BUFFER **)(&p_message)); if(mb_status==RVF_RED) { AUDIO_SEND_TRACE("AUDIO entity has no memory for driver notification",RV_TRACE_LEVEL_ERROR); return; } ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->header.msg_id=MMI_MIDI_STOP_CON; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id=p_audio_gbl_var->midi.channel_id; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer=NULL; if(return_path->callback_func==NULL) rvf_send_msg(return_path->addr_id, p_message); else { (*return_path->callback_func)((void *)(p_message)); rvf_free_buf((T_RVF_BUFFER *)p_message); } p_audio_gbl_var->midi.l1_state=WAIT_START_REQ; return; } rvf_start_timer(AUDIO_MIDI_L1_SIMUL_TIMER, RVF_MS_TO_TICKS(1000), AUDIO_MIDI_L1_SIMUL_ONE_SHOT_TIMER); } if(p_message->msg_id==MMI_MIDI_STOP_REQ) { rvf_stop_timer(AUDIO_MIDI_L1_SIMUL_TIMER); // send MMI_MIDI_STOP_CON message to the Riviera audio entity mb_status=rvf_get_buf(p_audio_gbl_var->mb_internal, sizeof(T_AUDIO_DRIVER_NOTIFICATION), (T_RVF_BUFFER **)(&p_message)); if(mb_status==RVF_RED) { AUDIO_SEND_TRACE("AUDIO entity has no memory for driver notification",RV_TRACE_LEVEL_ERROR); return; } ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->header.msg_id=MMI_MIDI_STOP_CON; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->channel_id=p_audio_gbl_var->midi.channel_id; ((T_AUDIO_DRIVER_NOTIFICATION *)p_message)->p_buffer=NULL; if(return_path->callback_func==NULL) rvf_send_msg(return_path->addr_id, p_message); else { (*return_path->callback_func)((void *)(p_message)); rvf_free_buf((T_RVF_BUFFER *)p_message); } p_audio_gbl_var->midi.l1_state=WAIT_START_REQ; return; } break; } #endif // _WINDOWS } #endif // #if (L1_MIDI == 1) #endif // #ifdef RVM_AUDIO_MAIN_SWE