2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2007, Digium, Inc.
6 * Russell Bryant <russell@digium.com>
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.
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.
22 * \brief Resample slinear audio
28 <depend>res_resample</depend>
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35 /* These are for SHRT_MAX and FLT_MAX -- { */
36 #if defined(__Darwin__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__CYGWIN__)
44 #include "asterisk/module.h"
45 #include "asterisk/translate.h"
47 #include "libresample.h"
49 #include "slin_resample_ex.h"
51 #define RESAMPLER_QUALITY 0
53 #define OUTBUF_SIZE 8096
55 struct slin16_to_slin8_pvt {
57 double resample_factor;
60 struct slin8_to_slin16_pvt {
62 double resample_factor;
65 static int slin16_to_slin8_new(struct ast_trans_pvt *pvt)
67 struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
69 resamp_pvt->resample_factor = 0.5;
71 if (!(resamp_pvt->resampler = resample_open(RESAMPLER_QUALITY, 0.5, 0.5)))
77 static int slin8_to_slin16_new(struct ast_trans_pvt *pvt)
79 struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
81 resamp_pvt->resample_factor = 2.0;
83 if (!(resamp_pvt->resampler = resample_open(RESAMPLER_QUALITY, 2.0, 2.0)))
89 static void slin16_to_slin8_destroy(struct ast_trans_pvt *pvt)
91 struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
93 if (resamp_pvt->resampler)
94 resample_close(resamp_pvt->resampler);
97 static void slin8_to_slin16_destroy(struct ast_trans_pvt *pvt)
99 struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
101 if (resamp_pvt->resampler)
102 resample_close(resamp_pvt->resampler);
105 static int resample_frame(struct ast_trans_pvt *pvt,
106 void *resampler, double resample_factor, struct ast_frame *f)
108 int total_in_buf_used = 0;
109 int total_out_buf_used = 0;
110 int16_t *in_buf = (int16_t *) f->data;
111 int16_t *out_buf = (int16_t *) pvt->outbuf + pvt->samples;
112 float in_buf_f[f->samples];
113 float out_buf_f[2048];
117 for (i = 0; i < f->samples; i++)
118 in_buf_f[i] = in_buf[i] * (FLT_MAX / SHRT_MAX);
120 while (total_in_buf_used < f->samples) {
121 int in_buf_used, out_buf_used;
123 out_buf_used = resample_process(resampler, resample_factor,
124 &in_buf_f[total_in_buf_used], f->samples - total_in_buf_used,
126 &out_buf_f[total_out_buf_used], ARRAY_LEN(out_buf_f) - total_out_buf_used);
128 if (out_buf_used < 0)
131 total_out_buf_used += out_buf_used;
132 total_in_buf_used += in_buf_used;
134 if (total_out_buf_used == ARRAY_LEN(out_buf_f)) {
135 ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size\n");
141 for (i = 0; i < total_out_buf_used; i++)
142 out_buf[i] = out_buf_f[i] * (SHRT_MAX / FLT_MAX);
144 pvt->samples += total_out_buf_used;
145 pvt->datalen += (total_out_buf_used * sizeof(int16_t));
150 static int slin16_to_slin8_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
152 struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
154 return resample_frame(pvt, resamp_pvt->resampler, resamp_pvt->resample_factor, f);
157 static int slin8_to_slin16_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
159 struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
161 return resample_frame(pvt, resamp_pvt->resampler, resamp_pvt->resample_factor, f);
164 static struct ast_frame *slin16_to_slin8_sample(void)
166 static struct ast_frame f = {
167 .frametype = AST_FRAME_VOICE,
168 .subclass = AST_FORMAT_SLINEAR16,
169 .datalen = sizeof(slin16_slin8_ex),
170 .samples = sizeof(slin16_slin8_ex) / sizeof(slin16_slin8_ex[0]),
171 .src = __PRETTY_FUNCTION__,
172 .data = slin16_slin8_ex,
178 static struct ast_frame *slin8_to_slin16_sample(void)
180 static struct ast_frame f = {
181 .frametype = AST_FRAME_VOICE,
182 .subclass = AST_FORMAT_SLINEAR,
183 .datalen = sizeof(slin8_slin16_ex),
184 .samples = sizeof(slin8_slin16_ex) / sizeof(slin8_slin16_ex[0]),
185 .src = __PRETTY_FUNCTION__,
186 .data = slin8_slin16_ex,
192 static struct ast_translator slin16_to_slin8 = {
193 .name = "slin16_to_slin8",
194 .srcfmt = AST_FORMAT_SLINEAR16,
195 .dstfmt = AST_FORMAT_SLINEAR,
196 .newpvt = slin16_to_slin8_new,
197 .destroy = slin16_to_slin8_destroy,
198 .framein = slin16_to_slin8_framein,
199 .sample = slin16_to_slin8_sample,
200 .desc_size = sizeof(struct slin16_to_slin8_pvt),
201 .buffer_samples = (OUTBUF_SIZE / sizeof(int16_t)),
202 .buf_size = OUTBUF_SIZE,
205 static struct ast_translator slin8_to_slin16 = {
206 .name = "slin8_to_slin16",
207 .srcfmt = AST_FORMAT_SLINEAR,
208 .dstfmt = AST_FORMAT_SLINEAR16,
209 .newpvt = slin8_to_slin16_new,
210 .destroy = slin8_to_slin16_destroy,
211 .framein = slin8_to_slin16_framein,
212 .sample = slin8_to_slin16_sample,
213 .desc_size = sizeof(struct slin8_to_slin16_pvt),
214 .buffer_samples = OUTBUF_SIZE,
215 .buf_size = OUTBUF_SIZE,
218 static int unload_module(void)
222 res |= ast_unregister_translator(&slin16_to_slin8);
223 res |= ast_unregister_translator(&slin8_to_slin16);
228 static int load_module(void)
232 res |= ast_register_translator(&slin16_to_slin8);
233 res |= ast_register_translator(&slin8_to_slin16);
235 return AST_MODULE_LOAD_SUCCESS;
238 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");