2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2011, Digium, Inc.
6 * Russell Bryant <russell@digium.com>
7 * David Vossel <dvossel@digium.com>
9 * See http://www.asterisk.org for more information about
10 * the Asterisk project. Please do not directly contact
11 * any of the maintainers of this project for assistance;
12 * the project provides a web site, mailing lists and IRC
13 * channels for your use.
15 * This program is free software, distributed under the terms of
16 * the GNU General Public License Version 2. See the LICENSE file
17 * at the top of the source tree.
23 * \brief Resample slinear audio
29 <support_level>core</support_level>
33 #include "speex/speex_resampler.h"
35 ASTERISK_REGISTER_FILE()
37 #include "asterisk/module.h"
38 #include "asterisk/translate.h"
39 #include "asterisk/slin.h"
41 #define OUTBUF_SIZE 8096
43 static struct ast_translator *translators;
44 static int trans_size;
45 static struct ast_codec codec_list[] = {
48 .type = AST_MEDIA_TYPE_AUDIO,
53 .type = AST_MEDIA_TYPE_AUDIO,
58 .type = AST_MEDIA_TYPE_AUDIO,
63 .type = AST_MEDIA_TYPE_AUDIO,
68 .type = AST_MEDIA_TYPE_AUDIO,
73 .type = AST_MEDIA_TYPE_AUDIO,
78 .type = AST_MEDIA_TYPE_AUDIO,
83 .type = AST_MEDIA_TYPE_AUDIO,
88 .type = AST_MEDIA_TYPE_AUDIO,
89 .sample_rate = 192000,
93 static int resamp_new(struct ast_trans_pvt *pvt)
97 if (!(pvt->pvt = speex_resampler_init(1, pvt->t->src_codec.sample_rate, pvt->t->dst_codec.sample_rate, 5, &err))) {
101 ast_assert(pvt->f.subclass.format == NULL);
102 pvt->f.subclass.format = ao2_bump(ast_format_cache_get_slin_by_rate(pvt->t->dst_codec.sample_rate));
107 static void resamp_destroy(struct ast_trans_pvt *pvt)
109 SpeexResamplerState *resamp_pvt = pvt->pvt;
111 speex_resampler_destroy(resamp_pvt);
114 static int resamp_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
116 SpeexResamplerState *resamp_pvt = pvt->pvt;
117 unsigned int out_samples = (OUTBUF_SIZE / sizeof(int16_t)) - pvt->samples;
118 unsigned int in_samples;
123 in_samples = f->datalen / 2;
125 speex_resampler_process_int(resamp_pvt,
129 pvt->outbuf.i16 + pvt->samples,
132 pvt->samples += out_samples;
133 pvt->datalen += out_samples * 2;
138 static int unload_module(void)
143 for (idx = 0; idx < trans_size; idx++) {
144 res |= ast_unregister_translator(&translators[idx]);
146 ast_free(translators);
151 static int load_module(void)
156 trans_size = ARRAY_LEN(codec_list) * (ARRAY_LEN(codec_list) - 1);
157 if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
158 return AST_MODULE_LOAD_FAILURE;
161 for (x = 0; x < ARRAY_LEN(codec_list); x++) {
162 for (y = 0; y < ARRAY_LEN(codec_list); y++) {
166 translators[idx].newpvt = resamp_new;
167 translators[idx].destroy = resamp_destroy;
168 translators[idx].framein = resamp_framein;
169 translators[idx].desc_size = 0;
170 translators[idx].buffer_samples = (OUTBUF_SIZE / sizeof(int16_t));
171 translators[idx].buf_size = OUTBUF_SIZE;
172 memcpy(&translators[idx].src_codec, &codec_list[x], sizeof(struct ast_codec));
173 memcpy(&translators[idx].dst_codec, &codec_list[y], sizeof(struct ast_codec));
174 snprintf(translators[idx].name, sizeof(translators[idx].name), "slin %ukhz -> %ukhz",
175 translators[idx].src_codec.sample_rate, translators[idx].dst_codec.sample_rate);
176 res |= ast_register_translator(&translators[idx]);
181 /* in case ast_register_translator() failed, we call unload_module() and
182 ast_unregister_translator won't fail.*/
185 return AST_MODULE_LOAD_FAILURE;
188 return AST_MODULE_LOAD_SUCCESS;
191 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");