![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
slinfactory.c
Go to the documentation of this file.
00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 2005, Anthony Minessale II. 00005 * 00006 * Anthony Minessale <anthmct@yahoo.com> 00007 * 00008 * See http://www.asterisk.org for more information about 00009 * the Asterisk project. Please do not directly contact 00010 * any of the maintainers of this project for assistance; 00011 * the project provides a web site, mailing lists and IRC 00012 * channels for your use. 00013 * 00014 * This program is free software, distributed under the terms of 00015 * the GNU General Public License Version 2. See the LICENSE file 00016 * at the top of the source tree. 00017 */ 00018 00019 /*! \file 00020 * 00021 * \brief A machine to gather up arbitrary frames and convert them 00022 * to raw slinear on demand. 00023 * 00024 * \author Anthony Minessale <anthmct@yahoo.com> 00025 */ 00026 00027 #include "asterisk.h" 00028 00029 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 43696 $") 00030 00031 #include <string.h> 00032 00033 #include "asterisk/frame.h" 00034 #include "asterisk/slinfactory.h" 00035 #include "asterisk/logger.h" 00036 #include "asterisk/translate.h" 00037 00038 void ast_slinfactory_init(struct ast_slinfactory *sf) 00039 { 00040 memset(sf, 0, sizeof(*sf)); 00041 sf->offset = sf->hold; 00042 } 00043 00044 void ast_slinfactory_destroy(struct ast_slinfactory *sf) 00045 { 00046 struct ast_frame *f; 00047 00048 if (sf->trans) { 00049 ast_translator_free_path(sf->trans); 00050 sf->trans = NULL; 00051 } 00052 00053 while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) 00054 ast_frfree(f); 00055 } 00056 00057 int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f) 00058 { 00059 struct ast_frame *frame, *frame_ptr; 00060 unsigned int x; 00061 00062 if (f->subclass != AST_FORMAT_SLINEAR) { 00063 if (sf->trans && f->subclass != sf->format) { 00064 ast_translator_free_path(sf->trans); 00065 sf->trans = NULL; 00066 } 00067 if (!sf->trans) { 00068 if ((sf->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) { 00069 ast_log(LOG_WARNING, "Cannot build a path from %s to slin\n", ast_getformatname(f->subclass)); 00070 return 0; 00071 } else { 00072 sf->format = f->subclass; 00073 } 00074 } 00075 } 00076 00077 if (!(frame = ast_frdup( (sf->trans) ? ast_translate(sf->trans, f, 0) : f ))) 00078 return 0; 00079 00080 x = 0; 00081 AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list) 00082 x++; 00083 00084 AST_LIST_INSERT_TAIL(&sf->queue, frame, frame_list); 00085 00086 sf->size += frame->samples; 00087 00088 return x; 00089 } 00090 00091 int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples) 00092 { 00093 struct ast_frame *frame_ptr; 00094 unsigned int sofar = 0, ineed, remain; 00095 short *frame_data, *offset = buf; 00096 00097 while (sofar < samples) { 00098 ineed = samples - sofar; 00099 00100 if (sf->holdlen) { 00101 if ((sofar + sf->holdlen) <= ineed) { 00102 memcpy(offset, sf->hold, sf->holdlen * sizeof(*offset)); 00103 sofar += sf->holdlen; 00104 offset += sf->holdlen; 00105 sf->holdlen = 0; 00106 sf->offset = sf->hold; 00107 } else { 00108 remain = sf->holdlen - ineed; 00109 memcpy(offset, sf->offset, ineed * sizeof(*offset)); 00110 sofar += ineed; 00111 sf->offset += ineed; 00112 sf->holdlen = remain; 00113 } 00114 continue; 00115 } 00116 00117 if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) { 00118 frame_data = frame_ptr->data; 00119 00120 if ((sofar + frame_ptr->samples) <= ineed) { 00121 memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset)); 00122 sofar += frame_ptr->samples; 00123 offset += frame_ptr->samples; 00124 } else { 00125 remain = frame_ptr->samples - ineed; 00126 memcpy(offset, frame_data, ineed * sizeof(*offset)); 00127 sofar += ineed; 00128 frame_data += ineed; 00129 memcpy(sf->hold, frame_data, remain * sizeof(*offset)); 00130 sf->holdlen = remain; 00131 } 00132 ast_frfree(frame_ptr); 00133 } else { 00134 break; 00135 } 00136 } 00137 00138 sf->size -= sofar; 00139 return sofar; 00140 } 00141 00142 unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf) 00143 { 00144 return sf->size; 00145 }