Wed Oct 28 11:51:02 2009

Asterisk developer's documentation


codec_g722.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2008, Digium, Inc.
00005  *
00006  * Matthew Fredrickson <creslin@digium.com>
00007  * Russell Bryant <russell@digium.com>
00008  *
00009  * Special thanks to Steve Underwood for the implementation
00010  * and for doing the 8khz<->g.722 direct translation code.
00011  *
00012  * See http://www.asterisk.org for more information about
00013  * the Asterisk project. Please do not directly contact
00014  * any of the maintainers of this project for assistance;
00015  * the project provides a web site, mailing lists and IRC
00016  * channels for your use.
00017  *
00018  * This program is free software, distributed under the terms of
00019  * the GNU General Public License Version 2. See the LICENSE file
00020  * at the top of the source tree.
00021  */
00022 
00023 /*! \file
00024  *
00025  * \brief codec_g722.c - translate between signed linear and ITU G.722-64kbps
00026  *
00027  * \author Matthew Fredrickson <creslin@digium.com>
00028  * \author Russell Bryant <russell@digium.com>
00029  *
00030  * \arg http://soft-switch.org/downloads/non-gpl-bits.tgz
00031  * \arg http://lists.digium.com/pipermail/asterisk-dev/2006-September/022866.html
00032  *
00033  * \ingroup codecs
00034  */
00035 
00036 #include "asterisk.h"
00037 
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 130129 $")
00039 
00040 #include "asterisk/linkedlists.h"
00041 #include "asterisk/module.h"
00042 #include "asterisk/config.h"
00043 #include "asterisk/translate.h"
00044 #include "asterisk/utils.h"
00045 
00046 #define BUFFER_SAMPLES   8096 /* size for the translation buffers */
00047 #define BUF_SHIFT 5
00048 
00049 /* Sample frame data */
00050 
00051 #include "g722/g722.h"
00052 #include "slin_g722_ex.h"
00053 #include "g722_slin_ex.h"
00054 
00055 struct g722_encoder_pvt {
00056    g722_encode_state_t g722;
00057 };
00058 
00059 struct g722_decoder_pvt {
00060    g722_decode_state_t g722;
00061 };
00062 
00063 /*! \brief init a new instance of g722_encoder_pvt. */
00064 static int lintog722_new(struct ast_trans_pvt *pvt)
00065 {
00066    struct g722_encoder_pvt *tmp = pvt->pvt;
00067 
00068    g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
00069 
00070    return 0;
00071 }
00072 
00073 static int lin16tog722_new(struct ast_trans_pvt *pvt)
00074 {
00075    struct g722_encoder_pvt *tmp = pvt->pvt;
00076 
00077    g722_encode_init(&tmp->g722, 64000, 0);
00078 
00079    return 0;
00080 }
00081 
00082 /*! \brief init a new instance of g722_encoder_pvt. */
00083 static int g722tolin_new(struct ast_trans_pvt *pvt)
00084 {
00085    struct g722_decoder_pvt *tmp = pvt->pvt;
00086 
00087    g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
00088 
00089    return 0;
00090 }
00091 
00092 static int g722tolin16_new(struct ast_trans_pvt *pvt)
00093 {
00094    struct g722_decoder_pvt *tmp = pvt->pvt;
00095 
00096    g722_decode_init(&tmp->g722, 64000, 0);
00097 
00098    return 0;
00099 }
00100 
00101 static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00102 {
00103    struct g722_decoder_pvt *tmp = pvt->pvt;
00104    int out_samples;
00105    int in_samples;
00106 
00107    /* g722_decode expects the samples to be in the invalid samples / 2 format */
00108    in_samples = f->samples / 2;
00109 
00110    out_samples = g722_decode(&tmp->g722, &pvt->outbuf.i16[pvt->samples * sizeof(int16_t)], 
00111       (uint8_t *) f->data.ptr, in_samples);
00112 
00113    pvt->samples += out_samples;
00114 
00115    pvt->datalen += (out_samples * sizeof(int16_t));
00116 
00117    return 0;
00118 }
00119 
00120 static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00121 {
00122    struct g722_encoder_pvt *tmp = pvt->pvt;
00123    int outlen;
00124 
00125    outlen = g722_encode(&tmp->g722, (&pvt->outbuf.ui8[pvt->datalen]), 
00126       (int16_t *) f->data.ptr, f->samples);
00127 
00128    pvt->samples += outlen * 2;
00129 
00130    pvt->datalen += outlen;
00131 
00132    return 0;
00133 }
00134 
00135 static struct ast_frame *g722tolin_sample(void)
00136 {
00137    static struct ast_frame f = {
00138       .frametype = AST_FRAME_VOICE,
00139       .subclass = AST_FORMAT_G722,
00140       .datalen = sizeof(g722_slin_ex),
00141       .samples = sizeof(g722_slin_ex) * 2,
00142       .src = __PRETTY_FUNCTION__,
00143       .data.ptr = g722_slin_ex,
00144    };
00145 
00146    return &f;
00147 }
00148 
00149 static struct ast_frame *g722tolin16_sample(void)
00150 {
00151    static struct ast_frame f = {
00152       .frametype = AST_FRAME_VOICE,
00153       .subclass = AST_FORMAT_G722,
00154       .datalen = sizeof(g722_slin_ex),
00155       .samples = sizeof(g722_slin_ex) * 2,
00156       .src = __PRETTY_FUNCTION__,
00157       .data.ptr = g722_slin_ex,
00158    };
00159 
00160    return &f;
00161 }
00162 
00163 static struct ast_frame *lintog722_sample (void)
00164 {
00165    static struct ast_frame f = {
00166       .frametype = AST_FRAME_VOICE,
00167       .subclass = AST_FORMAT_SLINEAR,
00168       .datalen = sizeof(slin_g722_ex),
00169       .samples = ARRAY_LEN(slin_g722_ex),
00170       .src = __PRETTY_FUNCTION__,
00171       .data.ptr = slin_g722_ex,
00172    };
00173 
00174    return &f;
00175 }
00176 
00177 static struct ast_frame *lin16tog722_sample (void)
00178 {
00179    static struct ast_frame f = {
00180       .frametype = AST_FRAME_VOICE,
00181       .subclass = AST_FORMAT_SLINEAR16,
00182       .datalen = sizeof(slin_g722_ex),
00183       .samples = ARRAY_LEN(slin_g722_ex),
00184       .src = __PRETTY_FUNCTION__,
00185       .data.ptr = slin_g722_ex,
00186    };
00187 
00188    return &f;
00189 }
00190 
00191 static struct ast_translator g722tolin = {
00192    .name = "g722tolin",
00193    .srcfmt = AST_FORMAT_G722,
00194    .dstfmt = AST_FORMAT_SLINEAR,
00195    .newpvt = g722tolin_new,   /* same for both directions */
00196    .framein = g722tolin_framein,
00197    .sample = g722tolin_sample,
00198    .desc_size = sizeof(struct g722_decoder_pvt),
00199    .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
00200    .buf_size = BUFFER_SAMPLES,
00201    .plc_samples = 160,
00202 };
00203 
00204 static struct ast_translator lintog722 = {
00205    .name = "lintog722",
00206    .srcfmt = AST_FORMAT_SLINEAR,
00207    .dstfmt = AST_FORMAT_G722,
00208    .newpvt = lintog722_new,   /* same for both directions */
00209    .framein = lintog722_framein,
00210    .sample = lintog722_sample,
00211    .desc_size = sizeof(struct g722_encoder_pvt),
00212    .buffer_samples = BUFFER_SAMPLES * 2,
00213    .buf_size = BUFFER_SAMPLES,
00214 };
00215 
00216 static struct ast_translator g722tolin16 = {
00217    .name = "g722tolin16",
00218    .srcfmt = AST_FORMAT_G722,
00219    .dstfmt = AST_FORMAT_SLINEAR16,
00220    .newpvt = g722tolin16_new, /* same for both directions */
00221    .framein = g722tolin_framein,
00222    .sample = g722tolin16_sample,
00223    .desc_size = sizeof(struct g722_decoder_pvt),
00224    .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
00225    .buf_size = BUFFER_SAMPLES,
00226    .plc_samples = 160,
00227 };
00228 
00229 static struct ast_translator lin16tog722 = {
00230    .name = "lin16tog722",
00231    .srcfmt = AST_FORMAT_SLINEAR16,
00232    .dstfmt = AST_FORMAT_G722,
00233    .newpvt = lin16tog722_new, /* same for both directions */
00234    .framein = lintog722_framein,
00235    .sample = lin16tog722_sample,
00236    .desc_size = sizeof(struct g722_encoder_pvt),
00237    .buffer_samples = BUFFER_SAMPLES * 2,
00238    .buf_size = BUFFER_SAMPLES,
00239 };
00240 
00241 static int parse_config(int reload)
00242 {
00243    struct ast_variable *var;
00244    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00245    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
00246 
00247    if (cfg == NULL)
00248       return 0;
00249    if (cfg == CONFIG_STATUS_FILEUNCHANGED)
00250       return 0;
00251    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
00252       if (!strcasecmp(var->name, "genericplc")) {
00253          g722tolin.useplc = ast_true(var->value) ? 1 : 0;
00254          ast_verb(3, "codec_g722: %susing generic PLC\n",
00255                g722tolin.useplc ? "" : "not ");
00256       }
00257    }
00258    ast_config_destroy(cfg);
00259    return 0;
00260 }
00261 
00262 static int reload(void)
00263 {
00264    if (parse_config(1))
00265       return AST_MODULE_LOAD_DECLINE;
00266    return AST_MODULE_LOAD_SUCCESS;
00267 }
00268 
00269 static int unload_module(void)
00270 {
00271    int res = 0;
00272 
00273    res |= ast_unregister_translator(&g722tolin);
00274    res |= ast_unregister_translator(&lintog722);
00275    res |= ast_unregister_translator(&g722tolin16);
00276    res |= ast_unregister_translator(&lin16tog722);
00277 
00278    return res;
00279 }
00280 
00281 static int load_module(void)
00282 {
00283    int res = 0;
00284 
00285    if (parse_config(0))
00286       return AST_MODULE_LOAD_DECLINE;
00287 
00288    res |= ast_register_translator(&g722tolin);
00289    res |= ast_register_translator(&lintog722);
00290    res |= ast_register_translator(&g722tolin16);
00291    res |= ast_register_translator(&lin16tog722);
00292 
00293    if (res) {
00294       unload_module();
00295       return AST_MODULE_LOAD_FAILURE;
00296    }  
00297 
00298    return AST_MODULE_LOAD_SUCCESS;
00299 }
00300 
00301 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
00302       .load = load_module,
00303       .unload = unload_module,
00304       .reload = reload,
00305           );

Generated on Wed Oct 28 11:51:02 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6