Thu Dec 17 23:51:13 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 - 2006, Digium, Inc.
00005  *
00006  * Matthew Fredrickson <creslin@digium.com>
00007  *
00008  * Special thanks to Steve Underwood for the implementation
00009  * and for doing the 8khz<->g.722 direct translation code.
00010  *
00011  * See http://www.asterisk.org for more information about
00012  * the Asterisk project. Please do not directly contact
00013  * any of the maintainers of this project for assistance;
00014  * the project provides a web site, mailing lists and IRC
00015  * channels for your use.
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief codec_g722.c - translate between signed linear and ITU G.722-64kbps
00025  *
00026  * \ingroup codecs
00027  */
00028 
00029 #include "asterisk.h"
00030 
00031 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 79747 $")
00032 
00033 #include <fcntl.h>
00034 #include <netinet/in.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <unistd.h>
00039 
00040 #include "asterisk/lock.h"
00041 #include "asterisk/logger.h"
00042 #include "asterisk/linkedlists.h"
00043 #include "asterisk/module.h"
00044 #include "asterisk/config.h"
00045 #include "asterisk/options.h"
00046 #include "asterisk/translate.h"
00047 #include "asterisk/channel.h"
00048 #include "asterisk/utils.h"
00049 
00050 #define BUFFER_SAMPLES   8096 /* size for the translation buffers */
00051 #define BUF_SHIFT 5
00052 
00053 /* Sample frame data */
00054 
00055 #include "g722/g722.h"
00056 #include "slin_g722_ex.h"
00057 #include "g722_slin_ex.h"
00058 
00059 struct g722_encoder_pvt {
00060    g722_encode_state_t g722;
00061 };
00062 
00063 struct g722_decoder_pvt {
00064    g722_decode_state_t g722;
00065 };
00066 
00067 /*! \brief init a new instance of g722_encoder_pvt. */
00068 static int lintog722_new(struct ast_trans_pvt *pvt)
00069 {
00070    struct g722_encoder_pvt *tmp = pvt->pvt;
00071 
00072    g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
00073 
00074    return 0;
00075 }
00076 
00077 /*! \brief init a new instance of g722_encoder_pvt. */
00078 static int g722tolin_new(struct ast_trans_pvt *pvt)
00079 {
00080    struct g722_decoder_pvt *tmp = pvt->pvt;
00081 
00082    g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
00083 
00084    return 0;
00085 }
00086 
00087 static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00088 {
00089    struct g722_decoder_pvt *tmp = pvt->pvt;
00090    unsigned char *src = f->data;
00091    int16_t *dst = (int16_t *) pvt->outbuf + pvt->samples;
00092 
00093    g722_decode(&tmp->g722, dst, src, f->samples);
00094    pvt->samples += f->samples;
00095    pvt->datalen += 2 * f->samples;
00096 
00097    return 0;
00098 }
00099 
00100 static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00101 {
00102    struct g722_encoder_pvt *tmp = pvt->pvt;
00103    int16_t *src = f->data;
00104 
00105    g722_encode(&tmp->g722, (uint8_t*)(&pvt->outbuf[pvt->datalen]), src, f->samples);
00106    /* Since G.722 64kbps per second is one bye per sample, all of these
00107       calculations are easy */
00108    pvt->samples += f->samples;
00109    pvt->datalen += f->samples;
00110 
00111    return 0;
00112 }
00113 
00114 static struct ast_frame *g722tolin_sample(void)
00115 {
00116    static struct ast_frame f = {
00117       .frametype = AST_FRAME_VOICE,
00118       .subclass = AST_FORMAT_G722,
00119       .datalen = sizeof(g722_slin_ex),
00120       .samples = sizeof(g722_slin_ex) / sizeof(g722_slin_ex[0]),
00121       .src = __PRETTY_FUNCTION__,
00122       .data = g722_slin_ex,
00123    };
00124 
00125    return &f;
00126 }
00127 
00128 static struct ast_frame *lintog722_sample (void)
00129 {
00130    static struct ast_frame f = {
00131       .frametype = AST_FRAME_VOICE,
00132       .subclass = AST_FORMAT_SLINEAR,
00133       .datalen = sizeof(slin_g722_ex),
00134       .samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]),
00135       .src = __PRETTY_FUNCTION__,
00136       .data = slin_g722_ex,
00137    };
00138 
00139    return &f;
00140 }
00141 
00142 static struct ast_translator g722tolin = {
00143    .name = "g722tolin",
00144    .srcfmt = AST_FORMAT_G722,
00145    .dstfmt = AST_FORMAT_SLINEAR,
00146    .newpvt = g722tolin_new,   /* same for both directions */
00147    .framein = g722tolin_framein,
00148    .sample = g722tolin_sample,
00149    .desc_size = sizeof(struct g722_decoder_pvt),
00150    .buffer_samples = BUFFER_SAMPLES,
00151    .buf_size = BUFFER_SAMPLES,
00152    .plc_samples = 160,
00153 };
00154 
00155 static struct ast_translator lintog722 = {
00156    .name = "lintog722",
00157    .srcfmt = AST_FORMAT_SLINEAR,
00158    .dstfmt = AST_FORMAT_G722,
00159    .newpvt = lintog722_new,   /* same for both directions */
00160    .framein = lintog722_framein,
00161    .sample = lintog722_sample,
00162    .desc_size = sizeof(struct g722_encoder_pvt),
00163    .buffer_samples = BUFFER_SAMPLES,
00164    .buf_size = BUFFER_SAMPLES,
00165 };
00166 
00167 static void parse_config(int reload)
00168 {
00169    struct ast_variable *var;
00170    struct ast_config *cfg = ast_config_load("codecs.conf");
00171 
00172    if (!cfg)
00173       return;
00174    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
00175       if (!strcasecmp(var->name, "genericplc")) {
00176          g722tolin.useplc = ast_true(var->value) ? 1 : 0;
00177          if (option_verbose > 2)
00178             ast_verbose(VERBOSE_PREFIX_3 "codec_g722: %susing generic PLC\n", g722tolin.useplc ? "" : "not ");
00179       }
00180    }
00181    ast_config_destroy(cfg);
00182 }
00183 
00184 static int reload(void)
00185 {
00186    parse_config(1);
00187 
00188    return 0;
00189 }
00190 
00191 static int unload_module(void)
00192 {
00193    int res = 0;
00194 
00195    res |= ast_unregister_translator(&g722tolin);
00196    res |= ast_unregister_translator(&lintog722);
00197 
00198    return res;
00199 }
00200 
00201 static int load_module(void)
00202 {
00203    int res = 0;
00204 
00205 
00206    parse_config(0);
00207 
00208    res |= ast_register_translator(&g722tolin);
00209    res |= ast_register_translator(&lintog722);
00210 
00211    if (res)
00212       unload_module();
00213 
00214    return res;
00215 }
00216 
00217 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
00218       .load = load_module,
00219       .unload = unload_module,
00220       .reload = reload,
00221           );

Generated on Thu Dec 17 23:51:13 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7