/* Handle the UniMRCP responses sent to channel add requests. */ static apt_bool_t speech_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { speech_channel_t *schannel; if (channel != NULL) schannel = (speech_channel_t *)mrcp_application_channel_object_get(channel); else schannel = NULL; ast_log(LOG_DEBUG, "(%s) speech_on_channel_add\n", schannel->name); if ((schannel != NULL) && (application != NULL) && (session != NULL) && (channel != NULL)) { if ((session != NULL) && (status == MRCP_SIG_STATUS_CODE_SUCCESS)) { const mpf_codec_descriptor_t *descriptor = descriptor = mrcp_application_sink_descriptor_get(channel); if (!descriptor) { ast_log(LOG_ERROR, "(%s) Unable to determine codec descriptor\n", schannel->name); speech_channel_set_state(schannel, SPEECH_CHANNEL_ERROR); ast_log(LOG_DEBUG, "(%s) Terminating MRCP session\n", schannel->name); if (!mrcp_application_session_terminate(session)) ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name); return FALSE; } schannel->rate = descriptor->sampling_rate; const char *codec_name = NULL; if (descriptor->name.length > 0) codec_name = descriptor->name.buf; else codec_name = "unknown"; ast_log(LOG_NOTICE, "(%s) Channel ready, codec=%s, sample rate=%d\n", schannel->name, codec_name, schannel->rate); speech_channel_set_state(schannel, SPEECH_CHANNEL_READY); } else { ast_log(LOG_ERROR, "(%s) Channel error!\n", schannel->name); if (session != NULL) { ast_log(LOG_DEBUG, "(%s) Terminating MRCP session\n", schannel->name); speech_channel_set_state(schannel, SPEECH_CHANNEL_ERROR); if (!mrcp_application_session_terminate(session)) ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name); } } } else ast_log(LOG_ERROR, "(unknown) channel error!\n"); return TRUE; }
/** Destroy ASR session */ static apt_bool_t asr_session_destroy_ex(asr_session_t *asr_session, apt_bool_t terminate) { if(terminate == TRUE) { apr_thread_mutex_lock(asr_session->mutex); if(mrcp_application_session_terminate(asr_session->mrcp_session) == TRUE) { apr_thread_cond_wait(asr_session->wait_object,asr_session->mutex); /* the response must be checked to be the valid one */ } apr_thread_mutex_unlock(asr_session->mutex); } if(asr_session->audio_in) { fclose(asr_session->audio_in); asr_session->audio_in = NULL; } if(asr_session->mutex) { apr_thread_mutex_destroy(asr_session->mutex); asr_session->mutex = NULL; } if(asr_session->wait_object) { apr_thread_cond_destroy(asr_session->wait_object); asr_session->wait_object = NULL; } if(asr_session->media_buffer) { mpf_frame_buffer_destroy(asr_session->media_buffer); asr_session->media_buffer = NULL; } return mrcp_application_session_destroy(asr_session->mrcp_session); }
/** Handle the responses sent to channel add requests */ static apt_bool_t synth_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { synth_app_channel_t *synth_channel = mrcp_application_channel_object_get(channel); if(status == MRCP_SIG_STATUS_CODE_SUCCESS) { mrcp_message_t *mrcp_message; const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application); /* create and send SPEAK request */ mrcp_message = demo_speak_message_create(session,channel,dir_layout); if(mrcp_message) { mrcp_application_message_send(session,channel,mrcp_message); } if(synth_channel && session) { char *file_name = apr_pstrcat(session->pool,"synth-",session->id.buf,".pcm",NULL); char *file_path = apt_datadir_filepath_get(dir_layout,file_name,session->pool); if(file_path) { synth_channel->audio_out = fopen(file_path,"wb"); } } } else { /* error case, just terminate the demo */ mrcp_application_session_terminate(session); } return TRUE; }
/** Handle the responses sent to channel add requests */ static apt_bool_t demo_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { if(status == MRCP_SIG_STATUS_CODE_SUCCESS) { mpf_rtp_termination_descriptor_t *rtp_descriptor; mrcp_message_t *mrcp_message; const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application); /* create and send SPEAK request */ mrcp_message = demo_speak_message_create(session,channel,dir_layout); if(mrcp_message) { mrcp_application_message_send(session,channel,mrcp_message); } rtp_descriptor = mrcp_application_rtp_descriptor_get(channel); if(rtp_descriptor) { mpf_rtp_media_descriptor_t *local_media = rtp_descriptor->audio.local; mpf_rtp_media_descriptor_t *remote_media = rtp_descriptor->audio.remote; if(local_media && remote_media) { apt_log(APT_PRIO_INFO,"Media Attributes: L[%s/%d] R[%s/%d]", local_media->base.ip.buf, local_media->base.port, remote_media->base.ip.buf, remote_media->base.port); } } } else { /* error case, just terminate the demo */ mrcp_application_session_terminate(session); } return TRUE; }
/* Handle the UniMRCP responses sent to channel remove requests. */ static apt_bool_t speech_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { speech_channel_t *schannel; if (channel != NULL) schannel = (speech_channel_t *)mrcp_application_channel_object_get(channel); else schannel = NULL; ast_log(LOG_DEBUG, "(%s) speech_on_channel_remove\n", schannel->name); if (schannel != NULL) { ast_log(LOG_NOTICE, "(%s) Channel removed\n", schannel->name); schannel->unimrcp_channel = NULL; if (session != NULL) { ast_log(LOG_DEBUG, "(%s) Terminating MRCP session\n", schannel->name); if (!mrcp_application_session_terminate(session)) ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name); } } else ast_log(LOG_ERROR, "(unknown) channel error!\n"); return TRUE; }
bool UmcSession::Terminate() { if(m_Terminating) return false; m_Running = false; m_Terminating = true; return (mrcp_application_session_terminate(m_pMrcpSession) == TRUE); }
/** Handle the responses sent to channel add requests */ static apt_bool_t synth_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { if(status == MRCP_SIG_STATUS_CODE_SUCCESS) { mrcp_message_t *mrcp_message; synth_app_channel_t *synth_channel = mrcp_application_channel_object_get(channel); apr_pool_t *pool = mrcp_application_session_pool_get(session); const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application); const mpf_codec_descriptor_t *descriptor = mrcp_application_sink_descriptor_get(channel); if(!descriptor) { /* terminate the demo */ apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Get Media Sink Descriptor"); return mrcp_application_session_terminate(session); } /* create and send SPEAK request */ mrcp_message = demo_speak_message_create(session,channel,dir_layout); if(mrcp_message) { mrcp_application_message_send(session,channel,mrcp_message); } if(synth_channel) { const apt_str_t *id = mrcp_application_session_id_get(session); char *file_name = apr_psprintf(pool,"synth-%dkHz-%s.pcm", descriptor->sampling_rate/1000, id->buf); char *file_path = apt_datadir_filepath_get(dir_layout,file_name,pool); if(file_path) { synth_channel->audio_out = fopen(file_path,"wb"); } } } else { /* error case, just terminate the demo */ mrcp_application_session_terminate(session); } return TRUE; }
/** Handle the responses sent to channel remove requests */ static apt_bool_t synth_application_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { synth_app_channel_t *synth_channel = mrcp_application_channel_object_get(channel); /* terminate the demo */ mrcp_application_session_terminate(session); if(synth_channel) { FILE *audio_out = synth_channel->audio_out; if(audio_out) { synth_channel->audio_out = NULL; fclose(audio_out); } } return TRUE; }
static apt_bool_t recog_application_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { recog_app_channel_t *recog_channel = mrcp_application_channel_object_get(channel); /* terminate the demo */ mrcp_application_session_terminate(session); if(recog_channel) { FILE *audio_in = recog_channel->audio_in; if(audio_in) { recog_channel->audio_in = NULL; fclose(audio_in); } } return TRUE; }
/** Handle the responses sent to channel add requests */ static apt_bool_t recog_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { if(status == MRCP_SIG_STATUS_CODE_SUCCESS) { mrcp_message_t *mrcp_message; const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application); /* create and send DEFINE-GRAMMAR request */ mrcp_message = demo_define_grammar_message_create(session,channel,dir_layout); if(mrcp_message) { mrcp_application_message_send(session,channel,mrcp_message); } } else { /* error case, just terminate the demo */ mrcp_application_session_terminate(session); } return TRUE; }
/** \brief Send session management request to client stack and wait for async response */ static apt_bool_t uni_recog_sm_request_send(uni_speech_t *uni_speech, mrcp_sig_command_e sm_request) { apt_bool_t res = FALSE; ast_log(LOG_DEBUG, "Send session request type:%d\n",sm_request); apr_thread_mutex_lock(uni_speech->mutex); uni_speech->is_sm_request = TRUE; uni_speech->sm_request = sm_request; switch(sm_request) { case MRCP_SIG_COMMAND_SESSION_UPDATE: res = mrcp_application_session_update(uni_speech->session); break; case MRCP_SIG_COMMAND_SESSION_TERMINATE: res = mrcp_application_session_terminate(uni_speech->session); break; case MRCP_SIG_COMMAND_CHANNEL_ADD: res = mrcp_application_channel_add(uni_speech->session,uni_speech->channel); break; case MRCP_SIG_COMMAND_CHANNEL_REMOVE: res = mrcp_application_channel_remove(uni_speech->session,uni_speech->channel); break; case MRCP_SIG_COMMAND_RESOURCE_DISCOVER: res = mrcp_application_resource_discover(uni_speech->session); break; default: break; } if(res == TRUE) { /* Wait for session response */ ast_log(LOG_DEBUG, "Wait for session response\n"); if(apr_thread_cond_timedwait(uni_speech->wait_object,uni_speech->mutex,MRCP_APP_REQUEST_TIMEOUT) != APR_SUCCESS) { ast_log(LOG_ERROR, "Failed to get response, request timed out\n"); uni_speech->sm_response = MRCP_SIG_STATUS_CODE_FAILURE; } ast_log(LOG_DEBUG, "Waked up, status code: %d\n",uni_speech->sm_response); } uni_speech->is_sm_request = FALSE; apr_thread_mutex_unlock(uni_speech->mutex); return res; }
/** Handle the responses sent to resource discover requests */ static apt_bool_t discover_application_on_resource_discover(mrcp_application_t *application, mrcp_session_t *session, mrcp_session_descriptor_t *descriptor, mrcp_sig_status_code_e status) { if(descriptor && status == MRCP_SIG_STATUS_CODE_SUCCESS) { int i; int count = descriptor->control_media_arr->nelts; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"On Resource Discover [%d]", count); for(i = 0; i < count; i++) { mrcp_control_descriptor_t *control_media = mrcp_session_control_media_get(descriptor,i); if(control_media) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"[%d] - %s", i,control_media->resource_name.buf); } } } else { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Failed to Discover Resources"); } mrcp_application_session_terminate(session); return TRUE; }
int main(int argc, char const* argv[]) { apr_pool_t* pool = NULL; apr_pool_t* spool = NULL; int i; struct iovec cattext[101]; static char const SP = ' '; char const* outfile; apr_status_t status; apt_dir_layout_t* dirLayout = NULL; mrcp_client_t* client = NULL; mrcp_application_t* app = NULL; mrcp_session_t* sess = NULL; mpf_stream_capabilities_t* caps = NULL; mpf_termination_t* term = NULL; mrcp_channel_t* chan = NULL; struct stat info; if (argc < 2) { puts("Usage:"); printf("\t%s \"This is a synthetic voice.\"", argv[0]); exit(1); } /* Just detect various directory layout constellations */ if (stat(ROOT_DIR, &info)) ROOT_DIR = ROOT_DIR2; if (stat(ROOT_DIR, &info)) ROOT_DIR = ROOT_DIR3; /* Initialize platform first */ if (apr_initialize() != APR_SUCCESS) FAIL("Cannot initialize APR platform"); pool = apt_pool_create(); if (!pool) FAIL("Not enough memory"); for (i = 0; (i < argc - 2) && (i < 50); i += 2) { cattext[2 * i].iov_base = (void*) argv[i + 1]; cattext[2 * i].iov_len = strlen(argv[i + 1]); cattext[2 * i + 1].iov_base = (void*) &SP; cattext[2 * i + 1].iov_len = 1; } cattext[2 * i].iov_base = (void*) argv[i + 1]; cattext[2 * i].iov_len = strlen(argv[i + 1]); text = apr_pstrcatv(pool, cattext, 2 * i + 1, NULL); if (!text) FAIL("Not enough memory"); outfile = apr_pstrcat(pool, ROOT_DIR, "/data/", PCM_OUT_FILE, NULL); printf("This is a sample C UniMRCP client synthesizer scenario.\n"); printf("Use client configuration from %s/conf/unimrcpclient.xml\n", ROOT_DIR); printf("Use profile %s\n", MRCP_PROFILE); printf("Synthesize text: `%s'\n", text); printf("Write output to file: %s\n", outfile); printf("\n"); printf("Press enter to start the session...\n"); (void) getchar(); apt_log_instance_create(APT_LOG_OUTPUT_NONE, APT_PRIO_DEBUG, pool); apt_log_ext_handler_set(UniSynth_logger); dirLayout = apt_default_dir_layout_create(ROOT_DIR, pool); /* Create and start the client in a root dir */ client = unimrcp_client_create(dirLayout); if (!client) FAIL("Cannot create UniMRCP client"); app = mrcp_application_create(UniSynthAppMsgHandler, NULL, mrcp_client_memory_pool_get(client)); if (!app) FAIL("Cannot create MRCP application"); if (!mrcp_client_application_register(client, app, "Sample C app")) FAIL("Cannot register MRCP application"); if (!mrcp_client_start(client)) FAIL("Cannot start MRCP client"); /* Create a session using MRCP profile MRCP_PROFILE */ sess = mrcp_application_session_create(app, MRCP_PROFILE, NULL); if (!sess) FAIL("Cannot create session"); spool = mrcp_application_session_pool_get(sess); /* Create audio termination with capabilities */ caps = mpf_stream_capabilities_create(STREAM_DIRECTION_SEND, spool); if (!caps) FAIL("Error creating capabilities"); if (!mpf_codec_capabilities_add(&caps->codecs, MPF_SAMPLE_RATE_8000, "LPCM")) FAIL("Error adding codec capabilities"); term = mrcp_application_audio_termination_create(sess, &stream_vtable, caps, NULL); if (!term) FAIL("Cannot create audio termination"); /* Add signaling channel (and start processing in OnAdd method */ f = fopen(outfile, "wb"); if (!f) FAIL("Cannot open output file"); status = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool); if (status != APR_SUCCESS) FAIL("Cannot create mutex"); status = apr_thread_cond_create(&cond, pool); if (status != APR_SUCCESS) FAIL("Cannot create condition variable"); chan = mrcp_application_channel_create(sess, MRCP_SYNTHESIZER_RESOURCE, term, NULL, NULL); if (!chan) FAIL("Cannot create channel"); if (!mrcp_application_channel_add(sess, chan)) FAIL("Cannot add channel"); /* Now wait until the processing finishes */ apr_thread_mutex_lock(mutex); while (err < 0) apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); cleanup: if (sess) mrcp_application_session_terminate(sess); if (f) fclose(f); if (client) mrcp_client_shutdown(client); if (app) mrcp_application_destroy(app); if (client) mrcp_client_destroy(client); apt_log_instance_destroy(); if (pool) apr_pool_destroy(pool); apr_terminate(); puts("Program finished, memory released. Press any key to exit."); (void) getchar(); return err; }
/** Handle the responses sent to channel remove requests */ static apt_bool_t demo_application_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status) { /* terminate the demo */ mrcp_application_session_terminate(session); return TRUE; }
/* Destroy the speech channel. */ int speech_channel_destroy(speech_channel_t *schannel) { if (schannel == NULL) { ast_log(LOG_ERROR, "Speech channel structure pointer is NULL\n"); return -1; } ast_log(LOG_DEBUG, "Destroy speech channel: Name=%s, Type=%s, Codec=%s, Rate=%u\n", schannel->name, speech_channel_type_to_string(schannel->type), schannel->codec, schannel->rate); if (schannel->mutex) apr_thread_mutex_lock(schannel->mutex); #if SPEECH_CHANNEL_DUMP if(schannel->stream_out) { fclose(schannel->stream_out); schannel->stream_out = NULL; } if(schannel->stream_in) { fclose(schannel->stream_in); schannel->stream_in = NULL; } #endif /* Destroy the channel and session if not already done. */ if (schannel->state != SPEECH_CHANNEL_CLOSED) { int warned = 0; if ((schannel->unimrcp_session != NULL) && (schannel->unimrcp_channel != NULL)) { if (!mrcp_application_session_terminate(schannel->unimrcp_session)) ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name); } ast_log(LOG_DEBUG, "(%s) Waiting for MRCP session to terminate\n", schannel->name); while (schannel->state != SPEECH_CHANNEL_CLOSED) { if (schannel->cond != NULL) { if ((apr_thread_cond_timedwait(schannel->cond, schannel->mutex, SPEECH_CHANNEL_TIMEOUT_USEC) == APR_TIMEUP) && (!warned)) { warned = 1; ast_log(LOG_WARNING, "(%s) MRCP session has not terminated after %d ms\n", schannel->name, SPEECH_CHANNEL_TIMEOUT_USEC / 1000); } } } } if (schannel->state != SPEECH_CHANNEL_CLOSED) { ast_log(LOG_ERROR, "(%s) Failed to destroy channel. Continuing\n", schannel->name); } if (schannel->dtmf_generator != NULL) { mpf_dtmf_generator_destroy(schannel->dtmf_generator); schannel->dtmf_generator = NULL; ast_log(LOG_DEBUG, "(%s) DTMF generator destroyed\n", schannel->name); } if (schannel->audio_queue != NULL) { if (audio_queue_destroy(schannel->audio_queue) != 0) ast_log(LOG_WARNING, "(%s) Unable to destroy channel audio queue\n",schannel->name); } if (schannel->mutex != NULL) apr_thread_mutex_unlock(schannel->mutex); if (schannel->cond != NULL) { if (apr_thread_cond_destroy(schannel->cond) != APR_SUCCESS) ast_log(LOG_WARNING, "(%s) Unable to destroy channel condition variable\n", schannel->name); } if (schannel->mutex != NULL) { if (apr_thread_mutex_destroy(schannel->mutex) != APR_SUCCESS) ast_log(LOG_WARNING, "(%s) Unable to destroy channel condition variable\n", schannel->name); } schannel->name = NULL; schannel->profile = NULL; schannel->application = NULL; schannel->unimrcp_session = NULL; schannel->unimrcp_channel = NULL; schannel->stream = NULL; schannel->dtmf_generator = NULL; schannel->pool = NULL; schannel->mutex = NULL; schannel->cond = NULL; schannel->audio_queue = NULL; schannel->codec = NULL; schannel->data = NULL; schannel->chan = NULL; return 0; }