Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:56 2009

## Asterisk developer's documentation

- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Directories

# 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  */
    00025
    00026 #include <string.h>
    00027
    00028 #include "asterisk.h"
    00029
    00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
    00031
    00032 #include "asterisk/slinfactory.h"
    00033 #include "asterisk/logger.h"
    00034 #include "asterisk/translate.h"
    00035
    00036
    00037 void ast_slinfactory_init(struct ast_slinfactory *sf)
    00038 {
    00039    memset(sf, 0, sizeof(struct ast_slinfactory));
    00040    sf->offset = sf->hold;
    00041    sf->queue = NULL;
    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 = sf->queue)) {
    00054       sf->queue = f->next;
    00055       ast_frfree(f);
    00056    }
    00057 }
    00058
    00059 int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f)
    00060 {
    00061    struct ast_frame *frame, *frame_ptr;
    00062
    00063    if (!f) {
    00064       return 0;
    00065    }
    00066
    00067    if (f->subclass != AST_FORMAT_SLINEAR) {
    00068       if (sf->trans && f->subclass != sf->format) {
    00069          ast_translator_free_path(sf->trans);
    00070          sf->trans = NULL;
    00071       }
    00072       if (!sf->trans) {
    00073          if ((sf->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
    00074             ast_log(LOG_WARNING, "Cannot build a path from %s to slin\n", ast_getformatname(f->subclass));
    00075             return 0;
    00076          } else {
    00077             sf->format = f->subclass;
    00078          }
    00079       }
    00080    }
    00081
    00082    if (sf->trans) {
    00083       frame = ast_translate(sf->trans, f, 0);
    00084    } else {
    00085       frame = ast_frdup(f);
    00086    }
    00087
    00088    if (frame) {
    00089       int x = 0;
    00090       for (frame_ptr = sf->queue; frame_ptr && frame_ptr->next; frame_ptr=frame_ptr->next) {
    00091          x++;
    00092       }
    00093       if (frame_ptr) {
    00094          frame_ptr->next = frame;
    00095       } else {
    00096          sf->queue = frame;
    00097       }
    00098       frame->next = NULL;
    00099       sf->size += frame->datalen;
    00100       return x;
    00101    }
    00102
    00103    return 0;
    00104
    00105 }
    00106
    00107 int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t bytes)
    00108 {
    00109    struct ast_frame *frame_ptr;
    00110    int sofar = 0, ineed, remain;
    00111    short *frame_data, *offset = buf;
    00112
    00113    while (sofar < bytes) {
    00114       ineed = bytes - sofar;
    00115
    00116       if (sf->holdlen) {
    00117          if ((sofar + sf->holdlen) <= ineed) {
    00118             memcpy(offset, sf->hold, sf->holdlen);
    00119             sofar += sf->holdlen;
    00120             offset += (sf->holdlen / sizeof(short));
    00121             sf->holdlen = 0;
    00122             sf->offset = sf->hold;
    00123          } else {
    00124             remain = sf->holdlen - ineed;
    00125             memcpy(offset, sf->offset, ineed);
    00126             sofar += ineed;
    00127             sf->offset += (ineed / sizeof(short));
    00128             sf->holdlen = remain;
    00129          }
    00130          continue;
    00131       }
    00132
    00133       if ((frame_ptr = sf->queue)) {
    00134          sf->queue = frame_ptr->next;
    00135          frame_data = frame_ptr->data;
    00136
    00137          if ((sofar + frame_ptr->datalen) <= ineed) {
    00138             memcpy(offset, frame_data, frame_ptr->datalen);
    00139             sofar += frame_ptr->datalen;
    00140             offset += (frame_ptr->datalen / sizeof(short));
    00141          } else {
    00142             remain = frame_ptr->datalen - ineed;
    00143             memcpy(offset, frame_data, ineed);
    00144             sofar += ineed;
    00145             frame_data += (ineed / sizeof(short));
    00146             memcpy(sf->hold, frame_data, remain);
    00147             sf->holdlen = remain;
    00148          }
    00149          ast_frfree(frame_ptr);
    00150       } else {
    00151          break;
    00152       }
    00153    }
    00154
    00155    sf->size -= sofar;
    00156    return sofar;
    00157 }
    00158
    00159
    00160
    00161