/** Create engine channel and sink media termination */ mrcp_engine_channel_t* mrcp_engine_sink_channel_create( mrcp_engine_t *engine, const mrcp_engine_channel_method_vtable_t *channel_vtable, const mpf_audio_stream_vtable_t *stream_vtable, void *method_obj, mpf_codec_descriptor_t *codec_descriptor, apr_pool_t *pool) { mpf_stream_capabilities_t *capabilities; mpf_audio_stream_t *audio_stream; mpf_termination_t *termination; capabilities = mpf_sink_stream_capabilities_create(pool); if(codec_descriptor) { mpf_codec_capabilities_add( &capabilities->codecs, mpf_sample_rate_mask_get(codec_descriptor->sampling_rate), codec_descriptor->name.buf); } else { mpf_codec_default_capabilities_add(&capabilities->codecs); } /* create audio stream */ audio_stream = mpf_audio_stream_create( method_obj, /* object to associate */ stream_vtable, /* virtual methods table of audio stream */ capabilities, /* stream capabilities */ pool); /* pool to allocate memory from */ if(!audio_stream) { return NULL; } audio_stream->tx_descriptor = codec_descriptor; /* create media termination */ termination = mpf_raw_termination_create( NULL, /* no object to associate */ audio_stream, /* audio stream */ NULL, /* no video stream */ pool); /* pool to allocate memory from */ /* create engine channel base */ return mrcp_engine_channel_create( engine, /* engine */ channel_vtable, /* virtual methods table of engine channel */ method_obj, /* object to associate */ termination, /* media termination, used to terminate audio stream */ pool); /* pool to allocate memory from */ }
SynthChannel* SynthSession::CreateSynthChannel() { mrcp_channel_t* pChannel; mpf_termination_t* pTermination; mpf_stream_capabilities_t* pCapabilities; apr_pool_t* pool = GetSessionPool(); /* create channel */ SynthChannel* pSynthChannel = new SynthChannel; /* create sink stream capabilities */ pCapabilities = mpf_sink_stream_capabilities_create(pool); GetScenario()->InitCapabilities(pCapabilities); static const mpf_audio_stream_vtable_t audio_stream_vtable = { NULL, NULL, NULL, NULL, NULL, NULL, WriteStream, NULL }; pTermination = CreateAudioTermination( &audio_stream_vtable, /* virtual methods table of audio stream */ pCapabilities, /* capabilities of audio stream */ pSynthChannel); /* object to associate */ pChannel = CreateMrcpChannel( MRCP_SYNTHESIZER_RESOURCE, /* MRCP resource identifier */ pTermination, /* media termination, used to terminate audio stream */ NULL, /* RTP descriptor, used to create RTP termination (NULL by default) */ pSynthChannel); /* object to associate */ if(!pChannel) { delete pSynthChannel; return NULL; } pSynthChannel->m_pMrcpChannel = pChannel; return pSynthChannel; }
static mpf_termination_t *speech_channel_create_mpf_termination(speech_channel_t *schannel) { mpf_termination_t *termination = NULL; mpf_stream_capabilities_t *capabilities = NULL; int sample_rates; if (schannel->type == SPEECH_CHANNEL_SYNTHESIZER) capabilities = mpf_sink_stream_capabilities_create(schannel->unimrcp_session->pool); else capabilities = mpf_source_stream_capabilities_create(schannel->unimrcp_session->pool); if (capabilities == NULL) ast_log(LOG_ERROR, "(%s) Unable to create capabilities\n", schannel->name); /* UniMRCP should transcode whatever the MRCP server wants to use into LPCM * (host-byte ordered L16) for us. Asterisk may not support all of these. */ if (schannel->rate == 16000) sample_rates = MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000; else if (schannel->rate == 32000) sample_rates = MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000 | MPF_SAMPLE_RATE_32000; else if (schannel->rate == 48000) sample_rates = MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000 | MPF_SAMPLE_RATE_48000; else sample_rates = MPF_SAMPLE_RATE_8000; /* TO DO : Check if all of these are supported on Asterisk for all codecs. */ if (strcasecmp(schannel->codec, "L16") == 0) mpf_codec_capabilities_add(&capabilities->codecs, sample_rates, "LPCM"); else mpf_codec_capabilities_add(&capabilities->codecs, sample_rates, schannel->codec); termination = mrcp_application_audio_termination_create( schannel->unimrcp_session, /* Session, termination belongs to. */ &schannel->application->audio_stream_vtable, /* Virtual methods table of audio stream. */ capabilities, /* Capabilities of audio stream. */ schannel); /* Object to associate. */ if (termination == NULL) ast_log(LOG_ERROR, "(%s) Unable to create termination\n", schannel->name); return termination; }
/** Create demo synthesizer channel */ static mrcp_channel_t* synth_application_channel_create(mrcp_session_t *session) { mrcp_channel_t *channel; mpf_termination_t *termination; mpf_stream_capabilities_t *capabilities; apr_pool_t *pool = mrcp_application_session_pool_get(session); /* create channel */ synth_app_channel_t *synth_channel = apr_palloc(pool,sizeof(synth_app_channel_t)); synth_channel->audio_out = NULL; /* create sink stream capabilities */ capabilities = mpf_sink_stream_capabilities_create(pool); /* add codec capabilities (Linear PCM) */ mpf_codec_capabilities_add( &capabilities->codecs, MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000, "LPCM"); #if 0 /* more capabilities can be added or replaced */ mpf_codec_capabilities_add( &capabilities->codecs, MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000, "PCMU"); #endif termination = mrcp_application_audio_termination_create( session, /* session, termination belongs to */ &audio_stream_vtable, /* virtual methods table of audio stream */ capabilities, /* capabilities of audio stream */ synth_channel); /* object to associate */ channel = mrcp_application_channel_create( session, /* session, channel belongs to */ MRCP_SYNTHESIZER_RESOURCE, /* MRCP resource identifier */ termination, /* media termination, used to terminate audio stream */ NULL, /* RTP descriptor, used to create RTP termination (NULL by default) */ synth_channel); /* object to associate */ return channel; }
static mrcp_engine_channel_t* recorder_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool) { mpf_stream_capabilities_t *capabilities; mpf_termination_t *termination; /* create recorder channel */ recorder_channel_t *recorder_channel = apr_palloc(pool,sizeof(recorder_channel_t)); recorder_channel->record_request = NULL; recorder_channel->stop_response = NULL; recorder_channel->detector = mpf_activity_detector_create(pool); recorder_channel->max_time = 0; recorder_channel->cur_time = 0; recorder_channel->cur_size = 0; recorder_channel->file_name = NULL; recorder_channel->audio_out = NULL; capabilities = mpf_sink_stream_capabilities_create(pool); mpf_codec_capabilities_add( &capabilities->codecs, MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000, "LPCM"); /* create media termination */ termination = mrcp_engine_audio_termination_create( recorder_channel, /* object to associate */ &audio_stream_vtable, /* virtual methods table of audio stream */ capabilities, /* stream capabilities */ pool); /* pool to allocate memory from */ /* create engine channel base */ recorder_channel->channel = mrcp_engine_channel_create( engine, /* engine */ &channel_vtable, /* virtual methods table of engine channel */ recorder_channel, /* object to associate */ termination, /* associated media termination */ pool); /* pool to allocate memory from */ return recorder_channel->channel; }
/** Create sink media termination */ MRCP_DECLARE(mpf_termination_t*) mrcp_application_sink_termination_create( mrcp_session_t *session, const mpf_audio_stream_vtable_t *stream_vtable, mpf_codec_descriptor_t *codec_descriptor, void *obj) { mpf_stream_capabilities_t *capabilities; mpf_audio_stream_t *audio_stream; capabilities = mpf_sink_stream_capabilities_create(session->pool); if(codec_descriptor) { mpf_codec_capabilities_add( &capabilities->codecs, mpf_sample_rate_mask_get(codec_descriptor->sampling_rate), codec_descriptor->name.buf); } else { mpf_codec_default_capabilities_add(&capabilities->codecs); } /* create audio stream */ audio_stream = mpf_audio_stream_create( obj, /* object to associate */ stream_vtable, /* virtual methods table of audio stream */ capabilities, /* stream capabilities */ session->pool); /* memory pool to allocate memory from */ if(!audio_stream) { return NULL; } audio_stream->tx_descriptor = codec_descriptor; /* create raw termination */ return mpf_raw_termination_create( NULL, /* no object to associate */ audio_stream, /* audio stream */ NULL, /* no video stream */ session->pool); /* memory pool to allocate memory from */ }