mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-26 22:30:28 +00:00 
			
		
		
		
	Patch by: junky Review: https://reviewboard.asterisk.org/r/1743/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@362307 65c4cc65-6c06-0410-ace0-fbb531ad65f3
		
			
				
	
	
		
			152 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Asterisk -- An open source telephony toolkit.
 | |
|  *
 | |
|  * Copyright (C) 2011, Digium, Inc.
 | |
|  *
 | |
|  * Russell Bryant <russell@digium.com>
 | |
|  * David Vossel <dvossel@digium.com>
 | |
|  *
 | |
|  * See http://www.asterisk.org for more information about
 | |
|  * the Asterisk project. Please do not directly contact
 | |
|  * any of the maintainers of this project for assistance;
 | |
|  * the project provides a web site, mailing lists and IRC
 | |
|  * channels for your use.
 | |
|  *
 | |
|  * This program is free software, distributed under the terms of
 | |
|  * the GNU General Public License Version 2. See the LICENSE file
 | |
|  * at the top of the source tree.
 | |
|  */
 | |
| 
 | |
| /*! 
 | |
|  * \file
 | |
|  *
 | |
|  * \brief Resample slinear audio
 | |
|  * 
 | |
|  * \ingroup codecs
 | |
|  */
 | |
| 
 | |
| /*** MODULEINFO
 | |
| 	<support_level>core</support_level>
 | |
|  ***/
 | |
| 
 | |
| #include "asterisk.h"
 | |
| #include "speex/speex_resampler.h"
 | |
| 
 | |
| ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 | |
| 
 | |
| #include "asterisk/module.h"
 | |
| #include "asterisk/translate.h"
 | |
| #include "asterisk/slin.h"
 | |
| 
 | |
| #define OUTBUF_SIZE   8096
 | |
| 
 | |
| static struct ast_translator *translators;
 | |
| static int trans_size;
 | |
| static int id_list[] = {
 | |
| 	AST_FORMAT_SLINEAR,
 | |
| 	AST_FORMAT_SLINEAR12,
 | |
| 	AST_FORMAT_SLINEAR16,
 | |
| 	AST_FORMAT_SLINEAR24,
 | |
| 	AST_FORMAT_SLINEAR32,
 | |
| 	AST_FORMAT_SLINEAR44,
 | |
| 	AST_FORMAT_SLINEAR48,
 | |
| 	AST_FORMAT_SLINEAR96,
 | |
| 	AST_FORMAT_SLINEAR192,
 | |
| };
 | |
| 
 | |
| static int resamp_new(struct ast_trans_pvt *pvt)
 | |
| {
 | |
| 	int err;
 | |
| 
 | |
| 	if (!(pvt->pvt = speex_resampler_init(1, ast_format_rate(&pvt->t->src_format), ast_format_rate(&pvt->t->dst_format), 5, &err))) {
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static void resamp_destroy(struct ast_trans_pvt *pvt)
 | |
| {
 | |
| 	SpeexResamplerState *resamp_pvt = pvt->pvt;
 | |
| 	speex_resampler_destroy(resamp_pvt);
 | |
| }
 | |
| 
 | |
| static int resamp_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 | |
| {
 | |
| 	SpeexResamplerState *resamp_pvt = pvt->pvt;
 | |
| 	unsigned int out_samples = (OUTBUF_SIZE / sizeof(int16_t)) - pvt->samples;
 | |
| 	unsigned int in_samples;
 | |
| 
 | |
| 	if (!f->datalen) {
 | |
| 		return -1;
 | |
| 	}
 | |
| 	in_samples = f->datalen / 2;
 | |
| 
 | |
| 	speex_resampler_process_int(resamp_pvt,
 | |
| 		0,
 | |
| 		f->data.ptr,
 | |
| 		&in_samples,
 | |
| 		pvt->outbuf.i16 + pvt->samples,
 | |
| 		&out_samples);
 | |
| 
 | |
| 	pvt->samples += out_samples;
 | |
| 	pvt->datalen += out_samples * 2;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int unload_module(void)
 | |
| {
 | |
| 	int res = 0;
 | |
| 	int idx;
 | |
| 
 | |
| 	for (idx = 0; idx < trans_size; idx++) {
 | |
| 		res |= ast_unregister_translator(&translators[idx]);
 | |
| 	}
 | |
| 	ast_free(translators);
 | |
| 
 | |
| 	return res;
 | |
| }
 | |
| 
 | |
| static int load_module(void)
 | |
| {
 | |
| 	int res = 0;
 | |
| 	int x, y, idx = 0;
 | |
| 
 | |
| 	trans_size = ARRAY_LEN(id_list) * ARRAY_LEN(id_list);
 | |
| 	if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
 | |
| 		return AST_MODULE_LOAD_FAILURE;
 | |
| 	}
 | |
| 
 | |
| 	for (x = 0; x < ARRAY_LEN(id_list); x++) {
 | |
| 		for (y = 0; y < ARRAY_LEN(id_list); y++) {
 | |
| 			if (x == y) {
 | |
| 				continue;
 | |
| 			}
 | |
| 			translators[idx].newpvt = resamp_new;
 | |
| 			translators[idx].destroy = resamp_destroy;
 | |
| 			translators[idx].framein = resamp_framein;
 | |
| 			translators[idx].desc_size = 0;
 | |
| 			translators[idx].buffer_samples = (OUTBUF_SIZE / sizeof(int16_t));
 | |
| 			translators[idx].buf_size = OUTBUF_SIZE;
 | |
| 			ast_format_set(&translators[idx].src_format, id_list[x], 0);
 | |
| 			ast_format_set(&translators[idx].dst_format, id_list[y], 0);
 | |
| 			snprintf(translators[idx].name, sizeof(translators[idx].name), "slin %dkhz -> %dkhz",
 | |
| 				ast_format_rate(&translators[idx].src_format), ast_format_rate(&translators[idx].dst_format));
 | |
| 			res |= ast_register_translator(&translators[idx]);
 | |
| 			idx++;
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 	/* in case ast_register_translator() failed, we call unload_module() and
 | |
| 	ast_unregister_translator won't fail.*/
 | |
| 	if (res) {
 | |
| 		unload_module();
 | |
| 		return AST_MODULE_LOAD_FAILURE;
 | |
| 	}
 | |
| 
 | |
| 	return AST_MODULE_LOAD_SUCCESS;
 | |
| }
 | |
| 
 | |
| AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");
 |