/* * OpenMRCP - Open Source Media Resource Control Protocol Stack * Copyright (C) 2007, Cepstral LLC * * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * Author(s): * Arsen Chaloyan * * Contributor(s): * */ #include #include "media_context.h" #include "audio_source.h" #include "audio_sink.h" struct media_connector_t { media_context_t base; media_frame_t media_frame; audio_source_t *source; audio_sink_t *sink; FILE *capture; }; static apr_status_t media_connector_destroy(media_context_t *context) { media_connector_t *connector = (media_connector_t*)context; if(connector->capture) { fclose(connector->capture); connector->capture = NULL; } return APR_SUCCESS; } static apr_status_t media_connector_audio_source_add(media_context_t *context, audio_source_t *source) { media_connector_t *connector = (media_connector_t*)context; if(connector->source != source) { connector->source = source; if(source->method_set->open) { source->method_set->open(source); } } return APR_SUCCESS; } static apr_status_t media_connector_audio_source_remove(media_context_t *context, audio_source_t *source) { media_connector_t *connector = (media_connector_t*)context; if(connector->source == source) { if(source->method_set->close) { source->method_set->close(source); } connector->source = NULL; } return APR_SUCCESS; } static apr_status_t media_connector_audio_sink_add(media_context_t *context, audio_sink_t *sink) { media_connector_t *connector = (media_connector_t*)context; if(connector->sink != sink) { connector->sink = sink; if(sink->method_set->open) { sink->method_set->open(sink); } } return APR_SUCCESS; } static apr_status_t media_connector_audio_sink_remove(media_context_t *context, audio_sink_t *sink) { media_connector_t *connector = (media_connector_t*)context; if(connector->sink == sink) { if(sink->method_set->close) { sink->method_set->close(sink); } connector->sink = NULL; } return APR_SUCCESS; } static apr_status_t media_connector_capture(media_connector_t *connector) { fwrite( connector->media_frame.codec_frame.buffer, 1, connector->media_frame.codec_frame.size, connector->capture); return APR_SUCCESS; } static apr_status_t media_connector_process(media_context_t *context) { media_connector_t *connector = (media_connector_t*)context; connector->media_frame.type = MEDIA_FRAME_TYPE_NONE; if(connector->source) { connector->source->method_set->read_frame(connector->source,&connector->media_frame); } if((connector->media_frame.type & MEDIA_FRAME_TYPE_AUDIO) == 0) { memset( connector->media_frame.codec_frame.buffer, 0, connector->media_frame.codec_frame.size); } if(connector->capture) { media_connector_capture(connector); } if(connector->sink) { connector->sink->method_set->write_frame(connector->sink,&connector->media_frame); } return APR_SUCCESS; } static const media_context_method_set_t method_set = { media_connector_destroy, media_connector_audio_source_add, media_connector_audio_source_remove, media_connector_audio_sink_add, media_connector_audio_sink_remove, media_connector_process }; media_context_t* media_connector_create(apr_uint16_t sampling_rate, apr_pool_t *pool) { media_connector_t *connector = apr_palloc(pool,sizeof(media_connector_t)); media_context_init(&connector->base,pool); connector->base.method_set = &method_set; connector->media_frame.codec_frame.size = 2 * CODEC_FRAME_TIME_BASE * sampling_rate / 1000; connector->media_frame.codec_frame.buffer = apr_palloc(pool,connector->media_frame.codec_frame.size); connector->source = NULL; connector->sink = NULL; connector->capture = NULL; #if 0 connector->capture = fopen("capture.pcm","wb"); #endif return &connector->base; }