Sat Apr 26 2014 22:01:35

Asterisk developer's documentation


codec_resample.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2011, Digium, Inc.
00005  *
00006  * Russell Bryant <russell@digium.com>
00007  * David Vossel <dvossel@digium.com>
00008  *
00009  * See http://www.asterisk.org for more information about
00010  * the Asterisk project. Please do not directly contact
00011  * any of the maintainers of this project for assistance;
00012  * the project provides a web site, mailing lists and IRC
00013  * channels for your use.
00014  *
00015  * This program is free software, distributed under the terms of
00016  * the GNU General Public License Version 2. See the LICENSE file
00017  * at the top of the source tree.
00018  */
00019 
00020 /*! 
00021  * \file
00022  *
00023  * \brief Resample slinear audio
00024  * 
00025  * \ingroup codecs
00026  */
00027 
00028 /*** MODULEINFO
00029    <support_level>core</support_level>
00030  ***/
00031 
00032 #include "asterisk.h"
00033 #include "speex/speex_resampler.h"
00034 
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 385582 $")
00036 
00037 #include "asterisk/module.h"
00038 #include "asterisk/translate.h"
00039 #include "asterisk/slin.h"
00040 
00041 #define OUTBUF_SIZE   8096
00042 
00043 static struct ast_translator *translators;
00044 static int trans_size;
00045 static int id_list[] = {
00046    AST_FORMAT_SLINEAR,
00047    AST_FORMAT_SLINEAR12,
00048    AST_FORMAT_SLINEAR16,
00049    AST_FORMAT_SLINEAR24,
00050    AST_FORMAT_SLINEAR32,
00051    AST_FORMAT_SLINEAR44,
00052    AST_FORMAT_SLINEAR48,
00053    AST_FORMAT_SLINEAR96,
00054    AST_FORMAT_SLINEAR192,
00055 };
00056 
00057 static int resamp_new(struct ast_trans_pvt *pvt)
00058 {
00059    int err;
00060 
00061    if (!(pvt->pvt = speex_resampler_init(1, ast_format_rate(&pvt->t->src_format), ast_format_rate(&pvt->t->dst_format), 5, &err))) {
00062       return -1;
00063    }
00064 
00065    return 0;
00066 }
00067 
00068 static void resamp_destroy(struct ast_trans_pvt *pvt)
00069 {
00070    SpeexResamplerState *resamp_pvt = pvt->pvt;
00071    speex_resampler_destroy(resamp_pvt);
00072 }
00073 
00074 static int resamp_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00075 {
00076    SpeexResamplerState *resamp_pvt = pvt->pvt;
00077    unsigned int out_samples = (OUTBUF_SIZE / sizeof(int16_t)) - pvt->samples;
00078    unsigned int in_samples;
00079 
00080    if (!f->datalen) {
00081       return -1;
00082    }
00083    in_samples = f->datalen / 2;
00084 
00085    speex_resampler_process_int(resamp_pvt,
00086       0,
00087       f->data.ptr,
00088       &in_samples,
00089       pvt->outbuf.i16 + pvt->samples,
00090       &out_samples);
00091 
00092    pvt->samples += out_samples;
00093    pvt->datalen += out_samples * 2;
00094 
00095    return 0;
00096 }
00097 
00098 static int unload_module(void)
00099 {
00100    int res = 0;
00101    int idx;
00102 
00103    for (idx = 0; idx < trans_size; idx++) {
00104       res |= ast_unregister_translator(&translators[idx]);
00105    }
00106    ast_free(translators);
00107 
00108    return res;
00109 }
00110 
00111 static int load_module(void)
00112 {
00113    int res = 0;
00114    int x, y, idx = 0;
00115 
00116    trans_size = ARRAY_LEN(id_list) * (ARRAY_LEN(id_list) - 1);
00117    if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
00118       return AST_MODULE_LOAD_FAILURE;
00119    }
00120 
00121    for (x = 0; x < ARRAY_LEN(id_list); x++) {
00122       for (y = 0; y < ARRAY_LEN(id_list); y++) {
00123          if (x == y) {
00124             continue;
00125          }
00126          translators[idx].newpvt = resamp_new;
00127          translators[idx].destroy = resamp_destroy;
00128          translators[idx].framein = resamp_framein;
00129          translators[idx].desc_size = 0;
00130          translators[idx].buffer_samples = (OUTBUF_SIZE / sizeof(int16_t));
00131          translators[idx].buf_size = OUTBUF_SIZE;
00132          ast_format_set(&translators[idx].src_format, id_list[x], 0);
00133          ast_format_set(&translators[idx].dst_format, id_list[y], 0);
00134          snprintf(translators[idx].name, sizeof(translators[idx].name), "slin %dkhz -> %dkhz",
00135             ast_format_rate(&translators[idx].src_format), ast_format_rate(&translators[idx].dst_format));
00136          res |= ast_register_translator(&translators[idx]);
00137          idx++;
00138       }
00139 
00140    }
00141    /* in case ast_register_translator() failed, we call unload_module() and
00142    ast_unregister_translator won't fail.*/
00143    if (res) {
00144       unload_module();
00145       return AST_MODULE_LOAD_FAILURE;
00146    }
00147 
00148    return AST_MODULE_LOAD_SUCCESS;
00149 }
00150 
00151 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");