Tue Aug 20 16:34:31 2013

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) 2007, Digium, Inc.
00005  *
00006  * Russell Bryant <russell@digium.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 /*! 
00020  * \file
00021  *
00022  * \brief Resample slinear audio
00023  * 
00024  * \note To install libresample, check it out of the following repository:
00025  * <code>$ svn co http://svn.digium.com/svn/thirdparty/libresample/trunk</code>
00026  *
00027  * \ingroup codecs
00028  */
00029 
00030 /*** MODULEINFO
00031    <depend>resample</depend>
00032    <support_level>core</support_level>
00033  ***/
00034 
00035 #include "asterisk.h"
00036 
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00038 
00039 /* These are for SHRT_MAX and FLT_MAX -- { */
00040 #if defined(__Darwin__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__CYGWIN__)
00041 #include <float.h>
00042 #else
00043 #include <values.h>
00044 #endif
00045 #include <limits.h>
00046 /* } */
00047 
00048 #include <libresample.h>
00049 
00050 #include "asterisk/module.h"
00051 #include "asterisk/translate.h"
00052 
00053 #include "asterisk/slin.h"
00054 
00055 #define RESAMPLER_QUALITY 1
00056 
00057 #define OUTBUF_SIZE   8096
00058 
00059 struct slin16_to_slin8_pvt {
00060    void *resampler;
00061    float resample_factor;
00062 };
00063 
00064 struct slin8_to_slin16_pvt {
00065    void *resampler;
00066    float resample_factor;
00067 };
00068 
00069 static int slin16_to_slin8_new(struct ast_trans_pvt *pvt)
00070 {
00071    struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
00072 
00073    resamp_pvt->resample_factor = 8000.0 / 16000.0;
00074 
00075    if (!(resamp_pvt->resampler = resample_open(RESAMPLER_QUALITY, resamp_pvt->resample_factor, resamp_pvt->resample_factor)))
00076       return -1;
00077 
00078    return 0;
00079 }
00080 
00081 static int slin8_to_slin16_new(struct ast_trans_pvt *pvt)
00082 {
00083    struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
00084 
00085    resamp_pvt->resample_factor = 16000.0 / 8000.0;
00086 
00087    if (!(resamp_pvt->resampler = resample_open(RESAMPLER_QUALITY, resamp_pvt->resample_factor, resamp_pvt->resample_factor)))
00088       return -1;
00089 
00090    return 0;
00091 }
00092 
00093 static void slin16_to_slin8_destroy(struct ast_trans_pvt *pvt)
00094 {
00095    struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
00096 
00097    if (resamp_pvt->resampler)
00098       resample_close(resamp_pvt->resampler);
00099 }
00100 
00101 static void slin8_to_slin16_destroy(struct ast_trans_pvt *pvt)
00102 {
00103    struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
00104 
00105    if (resamp_pvt->resampler)
00106       resample_close(resamp_pvt->resampler);
00107 }
00108 
00109 static int resample_frame(struct ast_trans_pvt *pvt,
00110    void *resampler, float resample_factor, struct ast_frame *f)
00111 {
00112    int total_in_buf_used = 0;
00113    int total_out_buf_used = 0;
00114    int16_t *in_buf = (int16_t *) f->data.ptr;
00115    int16_t *out_buf = pvt->outbuf.i16 + pvt->samples;
00116    float in_buf_f[f->samples];
00117    float out_buf_f[2048];
00118    int res = 0;
00119    int i;
00120 
00121    for (i = 0; i < f->samples; i++)
00122       in_buf_f[i] = in_buf[i] * (FLT_MAX / SHRT_MAX);
00123 
00124    while (total_in_buf_used < f->samples) {
00125       int in_buf_used, out_buf_used;
00126 
00127       out_buf_used = resample_process(resampler, resample_factor,
00128          &in_buf_f[total_in_buf_used], f->samples - total_in_buf_used,
00129          0, &in_buf_used,
00130          &out_buf_f[total_out_buf_used], ARRAY_LEN(out_buf_f) - total_out_buf_used);
00131 
00132       if (out_buf_used < 0)
00133          break;
00134 
00135       total_out_buf_used += out_buf_used;
00136       total_in_buf_used += in_buf_used;
00137 
00138       if (total_out_buf_used == ARRAY_LEN(out_buf_f)) {
00139          ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size\n");
00140          res = -1;
00141          break;
00142       }
00143    }
00144 
00145    for (i = 0; i < total_out_buf_used; i++)
00146       out_buf[i] = out_buf_f[i] * (SHRT_MAX / FLT_MAX);  
00147 
00148    pvt->samples += total_out_buf_used;
00149    pvt->datalen += (total_out_buf_used * sizeof(int16_t));
00150 
00151    return res;
00152 }
00153 
00154 static int slin16_to_slin8_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00155 {
00156    struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
00157    void *resampler = resamp_pvt->resampler;
00158    float resample_factor = resamp_pvt->resample_factor;
00159 
00160    return resample_frame(pvt, resampler, resample_factor, f);
00161 }
00162 
00163 static int slin8_to_slin16_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00164 {
00165    struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
00166    void *resampler = resamp_pvt->resampler;
00167    float resample_factor = resamp_pvt->resample_factor;
00168 
00169    return resample_frame(pvt, resampler, resample_factor, f);
00170 }
00171 
00172 static struct ast_translator slin16_to_slin8 = {
00173    .name = "slin16_to_slin8",
00174    .srcfmt = AST_FORMAT_SLINEAR16,
00175    .dstfmt = AST_FORMAT_SLINEAR,
00176    .newpvt = slin16_to_slin8_new,
00177    .destroy = slin16_to_slin8_destroy,
00178    .framein = slin16_to_slin8_framein,
00179    .sample = slin16_sample,
00180    .desc_size = sizeof(struct slin16_to_slin8_pvt),
00181    .buffer_samples = (OUTBUF_SIZE / sizeof(int16_t)),
00182    .buf_size = OUTBUF_SIZE,
00183 };
00184 
00185 static struct ast_translator slin8_to_slin16 = {
00186    .name = "slin8_to_slin16",
00187    .srcfmt = AST_FORMAT_SLINEAR,
00188    .dstfmt = AST_FORMAT_SLINEAR16,
00189    .newpvt = slin8_to_slin16_new,
00190    .destroy = slin8_to_slin16_destroy,
00191    .framein = slin8_to_slin16_framein,
00192    .sample = slin8_sample,
00193    .desc_size = sizeof(struct slin8_to_slin16_pvt),
00194    .buffer_samples = (OUTBUF_SIZE / sizeof(int16_t)),
00195    .buf_size = OUTBUF_SIZE,
00196 };
00197 
00198 static int unload_module(void)
00199 {
00200    int res = 0;
00201 
00202    res |= ast_unregister_translator(&slin16_to_slin8);
00203    res |= ast_unregister_translator(&slin8_to_slin16);
00204 
00205    return res;
00206 }
00207 
00208 static int load_module(void)
00209 {
00210    int res = 0;
00211 
00212    res |= ast_register_translator(&slin16_to_slin8);
00213    res |= ast_register_translator(&slin8_to_slin16);
00214 
00215    return AST_MODULE_LOAD_SUCCESS;
00216 }
00217 
00218 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");

Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1