FreeCalypso > hg > ffs-editor
diff src/cs/services/audio/audio_midi.c @ 0:92470e5d0b9e
src: partial import from FC Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 15 May 2020 01:28:16 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/services/audio/audio_midi.c Fri May 15 01:28:16 2020 +0000 @@ -0,0 +1,961 @@ +/****************************************************************************/ +/* */ +/* 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