⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codec_speex.c

📁 IP04是一个使用Blackfin开源硬件结合Asterisk开源软件建立的IPPBX系统.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 1999 - 2005, Digium, Inc. * * Mark Spencer <markster@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 Translate between signed linear and Speex (Open Codec) * * http://www.speex.org * \note This work was motivated by Jeremy McNamara  * hacked to be configurable by anthm and bkw 9/28/2004 * \ingroup codecs *//*** MODULEINFO	<depend>speex</depend> ***/#include "asterisk.h"ASTERISK_FILE_VERSION(__FILE__, "$Revision: 42477 $")#include <fcntl.h>#include <stdlib.h>#include <unistd.h>#include <netinet/in.h>#include <string.h>#include <stdio.h>#include <speex/speex.h>/* We require a post 1.1.8 version of Speex to enable preprocessing   and better type handling */   #ifdef _SPEEX_TYPES_H#include <speex/speex_preprocess.h>#endif#include "asterisk/lock.h"#include "asterisk/translate.h"#include "asterisk/module.h"#include "asterisk/config.h"#include "asterisk/options.h"#include "asterisk/logger.h"#include "asterisk/channel.h"#include "asterisk/utils.h"/* Sample frame data */#include "slin_speex_ex.h"#include "speex_slin_ex.h"/* codec variables */static int quality = 3;static int complexity = 2;static int enhancement = 0;static int vad = 0;static int vbr = 0;static float vbr_quality = 4;static int abr = 0;static int dtx = 0;	/* set to 1 to enable silence detection */static int preproc = 0;static int pp_vad = 0;static int pp_agc = 0;static float pp_agc_level = 8000; /* XXX what is this 8000 ? */static int pp_denoise = 0;static int pp_dereverb = 0;static float pp_dereverb_decay = 0.4;static float pp_dereverb_level = 0.3;#define TYPE_SILENCE	 0x2#define TYPE_HIGH	 0x0#define TYPE_LOW	 0x1#define TYPE_MASK	 0x3#define	BUFFER_SAMPLES	8000#define	SPEEX_SAMPLES	160struct speex_coder_pvt {	void *speex;	SpeexBits bits;	int framesize;	int silent_state;#ifdef _SPEEX_TYPES_H	SpeexPreprocessState *pp;	spx_int16_t buf[BUFFER_SAMPLES];#else	int16_t buf[BUFFER_SAMPLES];	/* input, waiting to be compressed */#endif};/* variables used to measure MIPs at run time */static unsigned int total_enc_cycles;static unsigned int total_dec_cycles;static unsigned int enc_calls;static unsigned int dec_calls;static unsigned int start_dec_cycles;static unsigned int start_enc_cycles;/* C-callable function to return value of CYCLES register */static unsigned int cycles(void) {  int ret;   __asm__ __volatile__   (   "%0 = CYCLES;\n\t"   : "=&d" (ret)   :   : "R1"   );   return ret;}static int lintospeex_new(struct ast_trans_pvt *pvt){	struct speex_coder_pvt *tmp = pvt->pvt;	if (!(tmp->speex = speex_encoder_init(&speex_nb_mode)))		return -1;	speex_bits_init(&tmp->bits);	speex_bits_reset(&tmp->bits);	speex_encoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);	speex_encoder_ctl(tmp->speex, SPEEX_SET_COMPLEXITY, &complexity);#ifdef _SPEEX_TYPES_H	if (preproc) {		tmp->pp = speex_preprocess_state_init(tmp->framesize, 8000); /* XXX what is this 8000 ? */		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_VAD, &pp_vad);		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC, &pp_agc);		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &pp_agc_level);		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DENOISE, &pp_denoise);		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB, &pp_dereverb);		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &pp_dereverb_decay);		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &pp_dereverb_level);	}#endif	if (!abr && !vbr) {		speex_encoder_ctl(tmp->speex, SPEEX_SET_QUALITY, &quality);		if (vad)			speex_encoder_ctl(tmp->speex, SPEEX_SET_VAD, &vad);	}	if (vbr) {		speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR, &vbr);		speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR_QUALITY, &vbr_quality);	}	if (abr)		speex_encoder_ctl(tmp->speex, SPEEX_SET_ABR, &abr);	if (dtx)		speex_encoder_ctl(tmp->speex, SPEEX_SET_DTX, &dtx); 	tmp->silent_state = 0;	return 0;}static int speextolin_new(struct ast_trans_pvt *pvt){	struct speex_coder_pvt *tmp = pvt->pvt;		if (!(tmp->speex = speex_decoder_init(&speex_nb_mode)))		return -1;	speex_bits_init(&tmp->bits);	speex_decoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);	if (enhancement)		speex_decoder_ctl(tmp->speex, SPEEX_SET_ENH, &enhancement);	return 0;}static struct ast_frame *lintospeex_sample(void){	static struct ast_frame f;	f.frametype = AST_FRAME_VOICE;	f.subclass = AST_FORMAT_SLINEAR;	f.datalen = sizeof(slin_speex_ex);	/* Assume 8000 Hz */	f.samples = sizeof(slin_speex_ex)/2;	f.mallocd = 0;	f.offset = 0;	f.src = __PRETTY_FUNCTION__;	f.data = slin_speex_ex;	return &f;}static struct ast_frame *speextolin_sample(void){	static struct ast_frame f;	f.frametype = AST_FRAME_VOICE;	f.subclass = AST_FORMAT_SPEEX;	f.datalen = sizeof(speex_slin_ex);	/* All frames are 20 ms long */	f.samples = SPEEX_SAMPLES;	f.mallocd = 0;	f.offset = 0;	f.src = __PRETTY_FUNCTION__;	f.data = speex_slin_ex;	return &f;}/*! \brief convert and store into outbuf */static int speextolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f){	struct speex_coder_pvt *tmp = pvt->pvt;	/* Assuming there's space left, decode into the current buffer at	   the tail location.  Read in as many frames as there are */	int x;	int res;	int16_t *dst = (int16_t *)pvt->outbuf;	/* XXX fout is a temporary buffer, may have different types */#ifdef _SPEEX_TYPES_H	spx_int16_t fout[1024];#else	float fout[1024];#endif	unsigned int t;	if (f->datalen == 0) {  /* Native PLC interpolation */		if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {			ast_log(LOG_WARNING, "Out of buffer space\n");			return -1;		}#ifdef _SPEEX_TYPES_H		speex_decode_int(tmp->speex, NULL, dst + pvt->samples);#else		speex_decode(tmp->speex, NULL, fout);		for (x=0;x<tmp->framesize;x++) {			dst[pvt->samples + x] = (int16_t)fout[x];		}#endif		pvt->samples += tmp->framesize;		return 0;	}	/* Read in bits */	speex_bits_read_from(&tmp->bits, f->data, f->datalen);	for (;;) {#ifdef _SPEEX_TYPES_H				t = cycles();		res = speex_decode_int(tmp->speex, &tmp->bits, fout);		total_dec_cycles += cycles() - t;		if (dec_calls++ == 200) {			unsigned int total_cycles = cycles() - start_dec_cycles;			start_dec_cycles = cycles();			if (option_verbose > 2)				ast_verbose(VERBOSE_PREFIX_3 "speex dec_calls  %d  total_cycles: %d  "					    "total_dec_cycles: %d dec CPU load: %6.3f%%\n", 					    dec_calls, total_cycles, total_dec_cycles, 					    100.0*(float)total_dec_cycles/total_cycles);			total_dec_cycles = 0;			dec_calls = 0;		}#else		res = speex_decode(tmp->speex, &tmp->bits, fout);#endif				if (res < 0)			break;		if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {			ast_log(LOG_WARNING, "Out of buffer space\n");			return -1;		}		for (x = 0 ; x < tmp->framesize; x++)			dst[pvt->samples + x] = (int16_t)fout[x];		pvt->samples += tmp->framesize;		pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -