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 /*** MODULEINFO
00037    <support_level>core</support_level>
00038  ***/
00039 
00040 #include "asterisk.h"
00041 
00042 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 419592 $")
00043 
00044 #include "asterisk/linkedlists.h"
00045 #include "asterisk/module.h"
00046 #include "asterisk/config.h"
00047 #include "asterisk/translate.h"
00048 #include "asterisk/utils.h"
00049 
00050 #define BUFFER_SAMPLES   8096 /* size for the translation buffers */
00051 #define BUF_SHIFT 5
00052 
00053 #include "g722/g722.h"
00054 
00055 /* Sample frame data */
00056 #include "asterisk/slin.h"
00057 #include "ex_g722.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 static int lin16tog722_new(struct ast_trans_pvt *pvt)
00078 {
00079    struct g722_encoder_pvt *tmp = pvt->pvt;
00080 
00081    g722_encode_init(&tmp->g722, 64000, 0);
00082 
00083    return 0;
00084 }
00085 
00086 /*! \brief init a new instance of g722_encoder_pvt. */
00087 static int g722tolin_new(struct ast_trans_pvt *pvt)
00088 {
00089    struct g722_decoder_pvt *tmp = pvt->pvt;
00090 
00091    g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
00092 
00093    return 0;
00094 }
00095 
00096 static int g722tolin16_new(struct ast_trans_pvt *pvt)
00097 {
00098    struct g722_decoder_pvt *tmp = pvt->pvt;
00099 
00100    g722_decode_init(&tmp->g722, 64000, 0);
00101 
00102    return 0;
00103 }
00104 
00105 static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00106 {
00107    struct g722_decoder_pvt *tmp = pvt->pvt;
00108    int out_samples;
00109    int in_samples;
00110 
00111    /* g722_decode expects the samples to be in the invalid samples / 2 format */
00112    in_samples = f->samples / 2;
00113 
00114    out_samples = g722_decode(&tmp->g722, &pvt->outbuf.i16[pvt->samples * sizeof(int16_t)], 
00115       (uint8_t *) f->data.ptr, in_samples);
00116 
00117    pvt->samples += out_samples;
00118 
00119    pvt->datalen += (out_samples * sizeof(int16_t));
00120 
00121    return 0;
00122 }
00123 
00124 static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00125 {
00126    struct g722_encoder_pvt *tmp = pvt->pvt;
00127    int outlen;
00128 
00129    outlen = g722_encode(&tmp->g722, (&pvt->outbuf.ui8[pvt->datalen]), 
00130       (int16_t *) f->data.ptr, f->samples);
00131 
00132    pvt->samples += outlen * 2;
00133 
00134    pvt->datalen += outlen;
00135 
00136    return 0;
00137 }
00138 
00139 static struct ast_translator g722tolin = {
00140    .name = "g722tolin",
00141    .src_codec = {
00142       .name = "g722",
00143       .type = AST_MEDIA_TYPE_AUDIO,
00144       .sample_rate = 16000,
00145    },
00146    .dst_codec = {
00147       .name = "slin",
00148       .type = AST_MEDIA_TYPE_AUDIO,
00149       .sample_rate = 8000,
00150    },
00151    .format = "slin",
00152    .newpvt = g722tolin_new,   /* same for both directions */
00153    .framein = g722tolin_framein,
00154    .sample = g722_sample,
00155    .desc_size = sizeof(struct g722_decoder_pvt),
00156    .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
00157    .buf_size = BUFFER_SAMPLES,
00158 };
00159 
00160 static struct ast_translator lintog722 = {
00161    .name = "lintog722",
00162    .src_codec = {
00163       .name = "slin",
00164       .type = AST_MEDIA_TYPE_AUDIO,
00165       .sample_rate = 8000,
00166    },
00167    .dst_codec = {
00168       .name = "g722",
00169       .type = AST_MEDIA_TYPE_AUDIO,
00170       .sample_rate = 16000,
00171    },
00172    .format = "g722",
00173    .newpvt = lintog722_new,   /* same for both directions */
00174    .framein = lintog722_framein,
00175    .sample = slin8_sample,
00176    .desc_size = sizeof(struct g722_encoder_pvt),
00177    .buffer_samples = BUFFER_SAMPLES * 2,
00178    .buf_size = BUFFER_SAMPLES,
00179 };
00180 
00181 static struct ast_translator g722tolin16 = {
00182    .name = "g722tolin16",
00183    .src_codec = {
00184       .name = "g722",
00185       .type = AST_MEDIA_TYPE_AUDIO,
00186       .sample_rate = 16000,
00187    },
00188    .dst_codec = {
00189       .name = "slin",
00190       .type = AST_MEDIA_TYPE_AUDIO,
00191       .sample_rate = 16000,
00192    },
00193    .format = "slin16",
00194    .newpvt = g722tolin16_new, /* same for both directions */
00195    .framein = g722tolin_framein,
00196    .sample = g722_sample,
00197    .desc_size = sizeof(struct g722_decoder_pvt),
00198    .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
00199    .buf_size = BUFFER_SAMPLES,
00200 };
00201 
00202 static struct ast_translator lin16tog722 = {
00203    .name = "lin16tog722",
00204    .src_codec = {
00205       .name = "slin",
00206       .type = AST_MEDIA_TYPE_AUDIO,
00207       .sample_rate = 16000,
00208    },
00209    .dst_codec = {
00210       .name = "g722",
00211       .type = AST_MEDIA_TYPE_AUDIO,
00212       .sample_rate = 16000,
00213    },
00214    .format = "g722",
00215    .newpvt = lin16tog722_new, /* same for both directions */
00216    .framein = lintog722_framein,
00217    .sample = slin16_sample,
00218    .desc_size = sizeof(struct g722_encoder_pvt),
00219    .buffer_samples = BUFFER_SAMPLES * 2,
00220    .buf_size = BUFFER_SAMPLES,
00221 };
00222 
00223 static int unload_module(void)
00224 {
00225    int res = 0;
00226 
00227    res |= ast_unregister_translator(&g722tolin);
00228    res |= ast_unregister_translator(&lintog722);
00229    res |= ast_unregister_translator(&g722tolin16);
00230    res |= ast_unregister_translator(&lin16tog722);
00231 
00232    return res;
00233 }
00234 
00235 static int load_module(void)
00236 {
00237    int res = 0;
00238 
00239    res |= ast_register_translator(&g722tolin);
00240    res |= ast_register_translator(&lintog722);
00241    res |= ast_register_translator(&g722tolin16);
00242    res |= ast_register_translator(&lin16tog722);
00243 
00244    if (res) {
00245       unload_module();
00246       return AST_MODULE_LOAD_FAILURE;
00247    }  
00248 
00249    return AST_MODULE_LOAD_SUCCESS;
00250 }
00251 
00252 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
00253       .support_level = AST_MODULE_SUPPORT_CORE,
00254       .load = load_module,
00255       .unload = unload_module,
00256           );

Generated on Thu Apr 16 06:27:30 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6