res_pjsip/res_pjsip_callerid: NULL check on caller id name string
[asterisk/asterisk.git] / codecs / codec_g722.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Matthew Fredrickson <creslin@digium.com>
7  * Russell Bryant <russell@digium.com>
8  *
9  * Special thanks to Steve Underwood for the implementation
10  * and for doing the 8khz<->g.722 direct translation code.
11  *
12  * See http://www.asterisk.org for more information about
13  * the Asterisk project. Please do not directly contact
14  * any of the maintainers of this project for assistance;
15  * the project provides a web site, mailing lists and IRC
16  * channels for your use.
17  *
18  * This program is free software, distributed under the terms of
19  * the GNU General Public License Version 2. See the LICENSE file
20  * at the top of the source tree.
21  */
22
23 /*! \file
24  *
25  * \brief codec_g722.c - translate between signed linear and ITU G.722-64kbps
26  *
27  * \author Matthew Fredrickson <creslin@digium.com>
28  * \author Russell Bryant <russell@digium.com>
29  *
30  * \arg http://soft-switch.org/downloads/non-gpl-bits.tgz
31  * \arg http://lists.digium.com/pipermail/asterisk-dev/2006-September/022866.html
32  *
33  * \ingroup codecs
34  */
35
36 /*** MODULEINFO
37         <support_level>core</support_level>
38  ***/
39
40 #include "asterisk.h"
41
42 #include "asterisk/linkedlists.h"
43 #include "asterisk/module.h"
44 #include "asterisk/config.h"
45 #include "asterisk/translate.h"
46 #include "asterisk/utils.h"
47
48 #define BUFFER_SAMPLES   8096   /* size for the translation buffers */
49 #define BUF_SHIFT       5
50
51 #include "g722/g722.h"
52
53 /* Sample frame data */
54 #include "asterisk/slin.h"
55 #include "ex_g722.h"
56
57 struct g722_encoder_pvt {
58         g722_encode_state_t g722;
59 };
60
61 struct g722_decoder_pvt {
62         g722_decode_state_t g722;
63 };
64
65 /*! \brief init a new instance of g722_encoder_pvt. */
66 static int lintog722_new(struct ast_trans_pvt *pvt)
67 {
68         struct g722_encoder_pvt *tmp = pvt->pvt;
69
70         g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
71
72         return 0;
73 }
74
75 static int lin16tog722_new(struct ast_trans_pvt *pvt)
76 {
77         struct g722_encoder_pvt *tmp = pvt->pvt;
78
79         g722_encode_init(&tmp->g722, 64000, 0);
80
81         return 0;
82 }
83
84 /*! \brief init a new instance of g722_encoder_pvt. */
85 static int g722tolin_new(struct ast_trans_pvt *pvt)
86 {
87         struct g722_decoder_pvt *tmp = pvt->pvt;
88
89         g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
90
91         return 0;
92 }
93
94 static int g722tolin16_new(struct ast_trans_pvt *pvt)
95 {
96         struct g722_decoder_pvt *tmp = pvt->pvt;
97
98         g722_decode_init(&tmp->g722, 64000, 0);
99
100         return 0;
101 }
102
103 static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
104 {
105         struct g722_decoder_pvt *tmp = pvt->pvt;
106         int out_samples;
107         int in_samples;
108
109         /* g722_decode expects the samples to be in the invalid samples / 2 format */
110         in_samples = f->samples / 2;
111
112         out_samples = g722_decode(&tmp->g722, &pvt->outbuf.i16[pvt->samples * sizeof(int16_t)], 
113                 (uint8_t *) f->data.ptr, in_samples);
114
115         pvt->samples += out_samples;
116
117         pvt->datalen += (out_samples * sizeof(int16_t));
118
119         return 0;
120 }
121
122 static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
123 {
124         struct g722_encoder_pvt *tmp = pvt->pvt;
125         int outlen;
126
127         outlen = g722_encode(&tmp->g722, (&pvt->outbuf.ui8[pvt->datalen]), 
128                 (int16_t *) f->data.ptr, f->samples);
129
130         pvt->samples += outlen * 2;
131
132         pvt->datalen += outlen;
133
134         return 0;
135 }
136
137 static struct ast_translator g722tolin = {
138         .name = "g722tolin",
139         .src_codec = {
140                 .name = "g722",
141                 .type = AST_MEDIA_TYPE_AUDIO,
142                 .sample_rate = 16000,
143         },
144         .dst_codec = {
145                 .name = "slin",
146                 .type = AST_MEDIA_TYPE_AUDIO,
147                 .sample_rate = 8000,
148         },
149         .format = "slin",
150         .newpvt = g722tolin_new,        /* same for both directions */
151         .framein = g722tolin_framein,
152         .sample = g722_sample,
153         .desc_size = sizeof(struct g722_decoder_pvt),
154         .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
155         .buf_size = BUFFER_SAMPLES,
156 };
157
158 static struct ast_translator lintog722 = {
159         .name = "lintog722",
160         .src_codec = {
161                 .name = "slin",
162                 .type = AST_MEDIA_TYPE_AUDIO,
163                 .sample_rate = 8000,
164         },
165         .dst_codec = {
166                 .name = "g722",
167                 .type = AST_MEDIA_TYPE_AUDIO,
168                 .sample_rate = 16000,
169         },
170         .format = "g722",
171         .newpvt = lintog722_new,        /* same for both directions */
172         .framein = lintog722_framein,
173         .sample = slin8_sample,
174         .desc_size = sizeof(struct g722_encoder_pvt),
175         .buffer_samples = BUFFER_SAMPLES * 2,
176         .buf_size = BUFFER_SAMPLES,
177 };
178
179 static struct ast_translator g722tolin16 = {
180         .name = "g722tolin16",
181         .src_codec = {
182                 .name = "g722",
183                 .type = AST_MEDIA_TYPE_AUDIO,
184                 .sample_rate = 16000,
185         },
186         .dst_codec = {
187                 .name = "slin",
188                 .type = AST_MEDIA_TYPE_AUDIO,
189                 .sample_rate = 16000,
190         },
191         .format = "slin16",
192         .newpvt = g722tolin16_new,      /* same for both directions */
193         .framein = g722tolin_framein,
194         .sample = g722_sample,
195         .desc_size = sizeof(struct g722_decoder_pvt),
196         .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
197         .buf_size = BUFFER_SAMPLES,
198 };
199
200 static struct ast_translator lin16tog722 = {
201         .name = "lin16tog722",
202         .src_codec = {
203                 .name = "slin",
204                 .type = AST_MEDIA_TYPE_AUDIO,
205                 .sample_rate = 16000,
206         },
207         .dst_codec = {
208                 .name = "g722",
209                 .type = AST_MEDIA_TYPE_AUDIO,
210                 .sample_rate = 16000,
211         },
212         .format = "g722",
213         .newpvt = lin16tog722_new,      /* same for both directions */
214         .framein = lintog722_framein,
215         .sample = slin16_sample,
216         .desc_size = sizeof(struct g722_encoder_pvt),
217         .buffer_samples = BUFFER_SAMPLES * 2,
218         .buf_size = BUFFER_SAMPLES,
219 };
220
221 static int unload_module(void)
222 {
223         int res = 0;
224
225         res |= ast_unregister_translator(&g722tolin);
226         res |= ast_unregister_translator(&lintog722);
227         res |= ast_unregister_translator(&g722tolin16);
228         res |= ast_unregister_translator(&lin16tog722);
229
230         return res;
231 }
232
233 static int load_module(void)
234 {
235         int res = 0;
236
237         res |= ast_register_translator(&g722tolin);
238         res |= ast_register_translator(&lintog722);
239         res |= ast_register_translator(&g722tolin16);
240         res |= ast_register_translator(&lin16tog722);
241
242         if (res) {
243                 unload_module();
244                 return AST_MODULE_LOAD_DECLINE;
245         }       
246
247         return AST_MODULE_LOAD_SUCCESS;
248 }
249
250 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
251         .support_level = AST_MODULE_SUPPORT_CORE,
252         .load = load_module,
253         .unload = unload_module,
254 );