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
24 * \arg http://svn.digium.com/svn/libresample/trunk
30 <depend>resample</depend>
35 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
37 /* These are for SHRT_MAX and FLT_MAX -- { */
38 #if defined(__Darwin__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__CYGWIN__)
46 #include <libresample.h>
48 #include "asterisk/module.h"
49 #include "asterisk/translate.h"
51 #include "slin_resample_ex.h"
53 #define RESAMPLER_QUALITY 1
55 #define OUTBUF_SIZE 8096
57 struct slin16_to_slin8_pvt
{
59 float resample_factor
;
62 struct slin8_to_slin16_pvt
{
64 float resample_factor
;
67 static int slin16_to_slin8_new(struct ast_trans_pvt
*pvt
)
69 struct slin16_to_slin8_pvt
*resamp_pvt
= pvt
->pvt
;
71 resamp_pvt
->resample_factor
= 0.5;
73 if (!(resamp_pvt
->resampler
= resample_open(RESAMPLER_QUALITY
, 0.5, 0.5)))
79 static int slin8_to_slin16_new(struct ast_trans_pvt
*pvt
)
81 struct slin8_to_slin16_pvt
*resamp_pvt
= pvt
->pvt
;
83 resamp_pvt
->resample_factor
= 2.0;
85 if (!(resamp_pvt
->resampler
= resample_open(RESAMPLER_QUALITY
, 2.0, 2.0)))
91 static void slin16_to_slin8_destroy(struct ast_trans_pvt
*pvt
)
93 struct slin16_to_slin8_pvt
*resamp_pvt
= pvt
->pvt
;
95 if (resamp_pvt
->resampler
)
96 resample_close(resamp_pvt
->resampler
);
99 static void slin8_to_slin16_destroy(struct ast_trans_pvt
*pvt
)
101 struct slin8_to_slin16_pvt
*resamp_pvt
= pvt
->pvt
;
103 if (resamp_pvt
->resampler
)
104 resample_close(resamp_pvt
->resampler
);
107 static int resample_frame(struct ast_trans_pvt
*pvt
,
108 void *resampler
, float resample_factor
, struct ast_frame
*f
)
110 int total_in_buf_used
= 0;
111 int total_out_buf_used
= 0;
112 int16_t *in_buf
= (int16_t *) f
->data
.ptr
;
113 int16_t *out_buf
= pvt
->outbuf
.i16
+ pvt
->samples
;
114 float in_buf_f
[f
->samples
];
115 float out_buf_f
[2048];
119 for (i
= 0; i
< f
->samples
; i
++)
120 in_buf_f
[i
] = in_buf
[i
] * (FLT_MAX
/ SHRT_MAX
);
122 while (total_in_buf_used
< f
->samples
) {
123 int in_buf_used
, out_buf_used
;
125 out_buf_used
= resample_process(resampler
, resample_factor
,
126 &in_buf_f
[total_in_buf_used
], f
->samples
- total_in_buf_used
,
128 &out_buf_f
[total_out_buf_used
], ARRAY_LEN(out_buf_f
) - total_out_buf_used
);
130 if (out_buf_used
< 0)
133 total_out_buf_used
+= out_buf_used
;
134 total_in_buf_used
+= in_buf_used
;
136 if (total_out_buf_used
== ARRAY_LEN(out_buf_f
)) {
137 ast_log(LOG_ERROR
, "Output buffer filled ... need to increase its size\n");
143 for (i
= 0; i
< total_out_buf_used
; i
++)
144 out_buf
[i
] = out_buf_f
[i
] * (SHRT_MAX
/ FLT_MAX
);
146 pvt
->samples
+= total_out_buf_used
;
147 pvt
->datalen
+= (total_out_buf_used
* sizeof(int16_t));
152 static int slin16_to_slin8_framein(struct ast_trans_pvt
*pvt
, struct ast_frame
*f
)
154 struct slin16_to_slin8_pvt
*resamp_pvt
= pvt
->pvt
;
155 void *resampler
= resamp_pvt
->resampler
;
156 float resample_factor
= resamp_pvt
->resample_factor
;
158 return resample_frame(pvt
, resampler
, resample_factor
, f
);
161 static int slin8_to_slin16_framein(struct ast_trans_pvt
*pvt
, struct ast_frame
*f
)
163 struct slin8_to_slin16_pvt
*resamp_pvt
= pvt
->pvt
;
164 void *resampler
= resamp_pvt
->resampler
;
165 float resample_factor
= resamp_pvt
->resample_factor
;
167 return resample_frame(pvt
, resampler
, resample_factor
, f
);
170 static struct ast_frame
*slin16_to_slin8_sample(void)
172 static struct ast_frame f
= {
173 .frametype
= AST_FRAME_VOICE
,
174 .subclass
= AST_FORMAT_SLINEAR16
,
175 .datalen
= sizeof(slin16_slin8_ex
),
176 .samples
= ARRAY_LEN(slin16_slin8_ex
),
177 .src
= __PRETTY_FUNCTION__
,
178 .data
.ptr
= slin16_slin8_ex
,
184 static struct ast_frame
*slin8_to_slin16_sample(void)
186 static struct ast_frame f
= {
187 .frametype
= AST_FRAME_VOICE
,
188 .subclass
= AST_FORMAT_SLINEAR
,
189 .datalen
= sizeof(slin8_slin16_ex
),
190 .samples
= ARRAY_LEN(slin8_slin16_ex
),
191 .src
= __PRETTY_FUNCTION__
,
192 .data
.ptr
= slin8_slin16_ex
,
198 static struct ast_translator slin16_to_slin8
= {
199 .name
= "slin16_to_slin8",
200 .srcfmt
= AST_FORMAT_SLINEAR16
,
201 .dstfmt
= AST_FORMAT_SLINEAR
,
202 .newpvt
= slin16_to_slin8_new
,
203 .destroy
= slin16_to_slin8_destroy
,
204 .framein
= slin16_to_slin8_framein
,
205 .sample
= slin16_to_slin8_sample
,
206 .desc_size
= sizeof(struct slin16_to_slin8_pvt
),
207 .buffer_samples
= (OUTBUF_SIZE
/ sizeof(int16_t)),
208 .buf_size
= OUTBUF_SIZE
,
211 static struct ast_translator slin8_to_slin16
= {
212 .name
= "slin8_to_slin16",
213 .srcfmt
= AST_FORMAT_SLINEAR
,
214 .dstfmt
= AST_FORMAT_SLINEAR16
,
215 .newpvt
= slin8_to_slin16_new
,
216 .destroy
= slin8_to_slin16_destroy
,
217 .framein
= slin8_to_slin16_framein
,
218 .sample
= slin8_to_slin16_sample
,
219 .desc_size
= sizeof(struct slin8_to_slin16_pvt
),
220 .buffer_samples
= (OUTBUF_SIZE
/ sizeof(int16_t)),
221 .buf_size
= OUTBUF_SIZE
,
224 static int unload_module(void)
228 res
|= ast_unregister_translator(&slin16_to_slin8
);
229 res
|= ast_unregister_translator(&slin8_to_slin16
);
234 static int load_module(void)
238 res
|= ast_register_translator(&slin16_to_slin8
);
239 res
|= ast_register_translator(&slin8_to_slin16
);
241 return AST_MODULE_LOAD_SUCCESS
;
244 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "SLIN Resampling Codec");