Sat Aug 6 00:39:28 2011

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/options.h"
00044 #include "asterisk/translate.h"
00045 #include "asterisk/utils.h"
00046 
00047 #define BUFFER_SAMPLES   8096 /* size for the translation buffers */
00048 #define BUF_SHIFT 5
00049 
00050 /* Sample frame data */
00051 
00052 #include "g722/g722.h"
00053 #include "slin_g722_ex.h"
00054 #include "g722_slin_ex.h"
00055 
00056 struct g722_encoder_pvt {
00057    g722_encode_state_t g722;
00058 };
00059 
00060 struct g722_decoder_pvt {
00061    g722_decode_state_t g722;
00062 };
00063 
00064 /*! \brief init a new instance of g722_encoder_pvt. */
00065 static int lintog722_new(struct ast_trans_pvt *pvt)
00066 {
00067    struct g722_encoder_pvt *tmp = pvt->pvt;
00068 
00069    g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
00070 
00071    return 0;
00072 }
00073 
00074 /*! \brief init a new instance of g722_encoder_pvt. */
00075 static int g722tolin_new(struct ast_trans_pvt *pvt)
00076 {
00077    struct g722_decoder_pvt *tmp = pvt->pvt;
00078 
00079    g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
00080 
00081    return 0;
00082 }
00083 
00084 static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00085 {
00086    struct g722_decoder_pvt *tmp = pvt->pvt;
00087    int out_samples;
00088    int in_samples;
00089 
00090    /* g722_decode expects the samples to be in the invalid samples / 2 format */
00091    in_samples = f->samples / 2;
00092 
00093    out_samples = g722_decode(&tmp->g722, (int16_t *) &pvt->outbuf[pvt->samples * sizeof(int16_t)], (uint8_t *) f->data, in_samples);
00094 
00095    pvt->samples += out_samples;
00096 
00097    pvt->datalen += (out_samples * sizeof(int16_t));
00098 
00099    return 0;
00100 }
00101 
00102 static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00103 {
00104    struct g722_encoder_pvt *tmp = pvt->pvt;
00105    int outlen;
00106 
00107    outlen = g722_encode(&tmp->g722, (uint8_t *) (&pvt->outbuf[pvt->datalen]), (int16_t *) f->data, f->samples);
00108 
00109 
00110    pvt->samples += outlen * 2;
00111 
00112    pvt->datalen += outlen;
00113 
00114    return 0;
00115 }
00116 
00117 static struct ast_frame *g722tolin_sample(void)
00118 {
00119    static struct ast_frame f = {
00120       .frametype = AST_FRAME_VOICE,
00121       .subclass = AST_FORMAT_G722,
00122       .datalen = sizeof(g722_slin_ex),
00123       .samples = sizeof(g722_slin_ex) * 2,
00124       .src = __PRETTY_FUNCTION__,
00125       .data = g722_slin_ex,
00126    };
00127 
00128    return &f;
00129 }
00130 
00131 static struct ast_frame *lintog722_sample (void)
00132 {
00133    static struct ast_frame f = {
00134       .frametype = AST_FRAME_VOICE,
00135       .subclass = AST_FORMAT_SLINEAR,
00136       .datalen = sizeof(slin_g722_ex),
00137       .samples = ARRAY_LEN(slin_g722_ex),
00138       .src = __PRETTY_FUNCTION__,
00139       .data = slin_g722_ex,
00140    };
00141 
00142    return &f;
00143 }
00144 
00145 static struct ast_translator g722tolin = {
00146    .name = "g722tolin",
00147    .srcfmt = AST_FORMAT_G722,
00148    .dstfmt = AST_FORMAT_SLINEAR,
00149    .newpvt = g722tolin_new,   /* same for both directions */
00150    .framein = g722tolin_framein,
00151    .sample = g722tolin_sample,
00152    .desc_size = sizeof(struct g722_decoder_pvt),
00153    .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
00154    .buf_size = BUFFER_SAMPLES,
00155    .plc_samples = 160,
00156 };
00157 
00158 static struct ast_translator lintog722 = {
00159    .name = "lintog722",
00160    .srcfmt = AST_FORMAT_SLINEAR,
00161    .dstfmt = AST_FORMAT_G722,
00162    .newpvt = lintog722_new,   /* same for both directions */
00163    .framein = lintog722_framein,
00164    .sample = lintog722_sample,
00165    .desc_size = sizeof(struct g722_encoder_pvt),
00166    .buffer_samples = BUFFER_SAMPLES * 2,
00167    .buf_size = BUFFER_SAMPLES,
00168 };
00169 
00170 static int parse_config(int reload)
00171 {
00172    struct ast_variable *var;
00173    struct ast_config *cfg = ast_config_load("codecs.conf");
00174 
00175    if (!cfg)
00176       return 0;
00177    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
00178       if (!strcasecmp(var->name, "genericplc")) {
00179          g722tolin.useplc = ast_true(var->value) ? 1 : 0;
00180          if (option_verbose > 2)
00181              ast_verbose(VERBOSE_PREFIX_3 "codec_g722: %susing generic PLC\n", g722tolin.useplc ? "" : "not ");
00182       }
00183    }
00184    ast_config_destroy(cfg);
00185    return 0;
00186 }
00187 
00188 static int reload(void)
00189 {
00190    if (parse_config(1))
00191       return AST_MODULE_LOAD_DECLINE;
00192    return AST_MODULE_LOAD_SUCCESS;
00193 }
00194 
00195 static int unload_module(void)
00196 {
00197    int res = 0;
00198 
00199    res |= ast_unregister_translator(&g722tolin);
00200    res |= ast_unregister_translator(&lintog722);
00201 
00202    return res;
00203 }
00204 
00205 static int load_module(void)
00206 {
00207    int res = 0;
00208 
00209    if (parse_config(0))
00210       return AST_MODULE_LOAD_DECLINE;
00211 
00212    res |= ast_register_translator(&g722tolin);
00213    res |= ast_register_translator(&lintog722);
00214 
00215    if (res) {
00216       unload_module();
00217       return AST_MODULE_LOAD_FAILURE;
00218    }  
00219 
00220    return AST_MODULE_LOAD_SUCCESS;
00221 }
00222 
00223 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
00224       .load = load_module,
00225       .unload = unload_module,
00226       .reload = reload,
00227           );

Generated on Sat Aug 6 00:39:28 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7