ami_testhooks.c automatically registers hook
[asterisk/asterisk.git] / codecs / codec_ulaw.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief codec_ulaw.c - translate between signed linear and ulaw
22  * 
23  * \ingroup codecs
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "asterisk/module.h"
31 #include "asterisk/config.h"
32 #include "asterisk/translate.h"
33 #include "asterisk/ulaw.h"
34 #include "asterisk/utils.h"
35
36 #define BUFFER_SAMPLES   8096   /* size for the translation buffers */
37
38 /* Sample frame data */
39 #include "asterisk/slin.h"
40 #include "ex_ulaw.h"
41
42 /*! \brief convert and store samples in outbuf */
43 static int ulawtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
44 {
45         int i = f->samples;
46         unsigned char *src = f->data.ptr;
47         int16_t *dst = pvt->outbuf.i16 + pvt->samples;
48
49         pvt->samples += i;
50         pvt->datalen += i * 2;  /* 2 bytes/sample */
51
52         /* convert and copy in outbuf */
53         while (i--)
54                 *dst++ = AST_MULAW(*src++);
55
56         return 0;
57 }
58
59 /*! \brief convert and store samples in outbuf */
60 static int lintoulaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
61 {
62         int i = f->samples;
63         char *dst = pvt->outbuf.c + pvt->samples;
64         int16_t *src = f->data.ptr;
65
66         pvt->samples += i;
67         pvt->datalen += i;      /* 1 byte/sample */
68
69         while (i--)
70                 *dst++ = AST_LIN2MU(*src++);
71
72         return 0;
73 }
74
75 /*!
76  * \brief The complete translator for ulawToLin.
77  */
78
79 static struct ast_translator ulawtolin = {
80         .name = "ulawtolin",
81         .srcfmt = AST_FORMAT_ULAW,
82         .dstfmt = AST_FORMAT_SLINEAR,
83         .framein = ulawtolin_framein,
84         .sample = ulaw_sample,
85         .buffer_samples = BUFFER_SAMPLES,
86         .buf_size = BUFFER_SAMPLES * 2,
87         .plc_samples = 160,
88 };
89
90 static struct ast_translator testlawtolin = {
91         .name = "testlawtolin",
92         .srcfmt = AST_FORMAT_TESTLAW,
93         .dstfmt = AST_FORMAT_SLINEAR,
94         .framein = ulawtolin_framein,
95         .sample = ulaw_sample,
96         .buffer_samples = BUFFER_SAMPLES,
97         .buf_size = BUFFER_SAMPLES * 2,
98         .plc_samples = 160,
99 };
100
101 /*!
102  * \brief The complete translator for LinToulaw.
103  */
104
105 static struct ast_translator lintoulaw = {
106         .name = "lintoulaw",
107         .srcfmt = AST_FORMAT_SLINEAR,
108         .dstfmt = AST_FORMAT_ULAW,
109         .framein = lintoulaw_framein,
110         .sample = slin8_sample,
111         .buf_size = BUFFER_SAMPLES,
112         .buffer_samples = BUFFER_SAMPLES,
113 };
114
115 static struct ast_translator lintotestlaw = {
116         .name = "lintotestlaw",
117         .srcfmt = AST_FORMAT_SLINEAR,
118         .dstfmt = AST_FORMAT_TESTLAW,
119         .framein = lintoulaw_framein,
120         .sample = slin8_sample,
121         .buf_size = BUFFER_SAMPLES,
122         .buffer_samples = BUFFER_SAMPLES,
123 };
124
125 static int parse_config(int reload)
126 {
127         struct ast_variable *var;
128         struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
129         struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
130         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
131                 return 0;
132         for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
133                 if (!strcasecmp(var->name, "genericplc")) {
134                         ulawtolin.useplc = ast_true(var->value) ? 1 : 0;
135                         ast_verb(3, "codec_ulaw: %susing generic PLC\n", ulawtolin.useplc ? "" : "not ");
136                 }
137         }
138         ast_config_destroy(cfg);
139         return 0;
140 }
141
142 static int reload(void)
143 {
144         if (parse_config(1))
145                 return AST_MODULE_LOAD_DECLINE;
146         return AST_MODULE_LOAD_SUCCESS;
147 }
148
149 static int unload_module(void)
150 {
151         int res;
152
153         res = ast_unregister_translator(&lintoulaw);
154         res |= ast_unregister_translator(&ulawtolin);
155         res |= ast_unregister_translator(&testlawtolin);
156         res |= ast_unregister_translator(&lintotestlaw);
157
158         return res;
159 }
160
161 static int load_module(void)
162 {
163         int res;
164
165         if (parse_config(0))
166                 return AST_MODULE_LOAD_DECLINE;
167         res = ast_register_translator(&ulawtolin);
168         if (!res) {
169                 res = ast_register_translator(&lintoulaw);
170                 res |= ast_register_translator(&lintotestlaw);
171                 res |= ast_register_translator(&testlawtolin);
172         } else
173                 ast_unregister_translator(&ulawtolin);
174         if (res)
175                 return AST_MODULE_LOAD_FAILURE;
176         return AST_MODULE_LOAD_SUCCESS;
177 }
178
179 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "mu-Law Coder/Decoder",
180                 .load = load_module,
181                 .unload = unload_module,
182                 .reload = reload,
183                );