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

📄 codecs.c

📁 Intercom 是一个 Unix系统上灵活的语音传输软件。支持标准音频压缩比如GSM, G.711, and G.72x和其他音频编码。Intercom专为高速网络设计来传输高品质的语音
💻 C
字号:
/*  codecs.c -- Audio CODEC interface for Intercom    Copyright (C) 2001-2003  Shane Wegner    This file is part of Intercom.    Intercom is free software; you can redistribute it and/or modify it    under the terms of version 2 of the GNU General Public License as    published by the Free Software Foundation.    Intercom is distributed in the hope that it will be useful, but    WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    General Public License for more details.    You should have received a copy of version 2 of the GNU General Public    License along with Intercom; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    To contact the author, please send email to shane@cm.nu.    *//* $Id: codecs.c,v 1.7 2003/02/13 20:22:49 shane Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#ifdef HAVE_LIBGSM#ifdef HAVE_GSM_GSM_H#include <gsm/gsm.h>#else#include <gsm.h>#endif#endif#ifdef USE_GETTEXT#include <libintl.h>#define _(String) gettext(String)#define gettext_noop(String) (String)#define N_(String) gettext_noop(String)#else#define _(String) (String)#define N_(String) (String)#endif#include "codecs.h"#include "protocol.h"#include "iobuff.h"#include "g711.h"#ifdef HAVE_G72X#include "g72x.h"#endif#ifdef HAVE_LIBGSMstatic int g_init = 0;static gsm g_handle;static void codec_gsm_encode(const char *buff, size_t n, struct iobuff *iobout){static char left[320];static size_t leftbytes = 0;char frame[(n + leftbytes) / 320 * 33];size_t i;size_t buffpos = 0, framepos = 0;if (leftbytes) {i = ((320 - leftbytes) > n) ? n : 320 - leftbytes;memcpy(&left[leftbytes], buff, i);gsm_encode(g_handle, (gsm_signal *)left, &frame[framepos]);framepos += 33;buffpos += i;leftbytes = 0;}while((n - buffpos) >= 320) {gsm_encode(g_handle, (gsm_signal *)&buff[buffpos], &frame[framepos]);buffpos += 320;framepos += 33;}if (buffpos < n) {leftbytes = n - buffpos;memcpy(left, &buff[buffpos], leftbytes);}if (framepos)iob_queue(iobout, frame, framepos);}static void codec_gsm_decode(const char *buff, size_t n, struct iobuff *iobout){static char left[33];static size_t leftbytes = 0;char outbuff[(n + leftbytes) / 33 * 320];size_t i;size_t buffpos = 0, outpos = 0;if (leftbytes) {i = ((33 - leftbytes) > n) ? n : 33 - leftbytes;memcpy(&left[leftbytes], buff, i);gsm_decode(g_handle, left, (gsm_signal *)&outbuff[outpos]);outpos += 320;buffpos += i;leftbytes = 0;}while((n - buffpos) >= 33) {gsm_decode(g_handle, (char *)&buff[buffpos], (gsm_signal *)&outbuff[outpos]);buffpos += 33;outpos += 320;}if (buffpos < n) {leftbytes = n - buffpos;memcpy(left, &buff[buffpos], leftbytes);}if (outpos)iob_queue(iobout, outbuff, outpos);}#endifstatic void codec_g711u_encode(const char *buff, size_t n, struct iobuff *iobout){char outbuff[n / 2];size_t i;for (i = 0; i < n / 2; i++)outbuff[i] = linear2ulaw(((short *)buff)[i]);iob_queue(iobout, outbuff, n / 2);}static void codec_g711u_decode(const char *buff, size_t n, struct iobuff *iobout){short outbuff[n];size_t i;for (i = 0; i < n; i++)outbuff[i] = ulaw2linear(buff[i]);iob_queue(iobout, (char *)outbuff, n * 2);}static void codec_g711a_encode(const char *buff, size_t n, struct iobuff *iobout){char outbuff[n / 2];size_t i;for (i = 0; i < n / 2; i++)outbuff[i] = linear2alaw(((short *)buff)[i]);iob_queue(iobout, outbuff, n / 2);}static void codec_g711a_decode(const char *buff, size_t n, struct iobuff *iobout){short outbuff[n];size_t i;for (i = 0; i < n; i++)outbuff[i] = ulaw2linear(buff[i]);iob_queue(iobout, (char *)outbuff, n * 2);}#ifdef HAVE_G72Xstatic struct g72x_state g72xe_state, g72xd_state;static unsigned int out_buffer = 0, in_buffer = 0;static int out_bits = 0, in_bits = 0;static void codec_g72x_encode(int format, const char *buff,size_t n, struct iobuff *iobout){int (*enc_routine)();int enc_bits;size_t i;size_t outpos = 0;char outbuff[n];switch(format) {case AUDIO_COMPRESSION_G723_24:enc_routine = g723_24_encoder;enc_bits = 3;break;case AUDIO_COMPRESSION_G723_40:enc_routine = g723_40_encoder;enc_bits = 5;break;default:enc_routine = g721_encoder;enc_bits = 4;}for (i = 0; i < (n/2); i++) {out_buffer |= ((unsigned char)enc_routine(((short *)buff)[i],AUDIO_ENCODING_LINEAR, &g72xe_state) << out_bits);out_bits += enc_bits;if (out_bits >= 8) {outbuff[outpos++] = out_buffer & 0xff;out_bits -= 8;out_buffer >>= 8;}}iob_queue(iobout, outbuff, outpos);}static void codec_g72x_decode(int format, const char *buff,size_t n, struct iobuff *iobout){int (*dec_routine)();int dec_bits;size_t i = 0, outpos = 0;short outbuff[n*3];switch(format) {case AUDIO_COMPRESSION_G723_24:dec_routine = g723_24_decoder;dec_bits = 3;break;case AUDIO_COMPRESSION_G723_40:dec_routine = g723_40_decoder;dec_bits = 5;break;default:dec_routine = g721_decoder;dec_bits = 4;}while (i < n) {if (in_bits < dec_bits) {in_buffer |= ((unsigned char)buff[i++] << in_bits);in_bits += 8;}outbuff[outpos++] = dec_routine(in_buffer & ((1 << dec_bits) - 1),AUDIO_ENCODING_LINEAR, &g72xd_state);in_buffer >>= dec_bits;in_bits -= dec_bits;}iob_queue(iobout, (char *)outbuff, outpos*2);}#endifint codec_encode(int format, const char *buff, size_t n, struct iobuff *iobout){switch(format) {case AUDIO_COMPRESSION_NONE:iob_queue(iobout, buff, n);break;#ifdef HAVE_LIBGSMcase AUDIO_COMPRESSION_GSM:codec_gsm_encode(buff, n, iobout);break;#endifcase AUDIO_COMPRESSION_G711U:codec_g711u_encode(buff, n, iobout);break;case AUDIO_COMPRESSION_G711A:codec_g711a_encode(buff, n, iobout);break;#ifdef HAVE_G72Xcase AUDIO_COMPRESSION_G721:case AUDIO_COMPRESSION_G723_24:case AUDIO_COMPRESSION_G723_40:codec_g72x_encode(format, buff, n, iobout);break;#endifdefault:fprintf(stderr, _("Error: codec_encode called with invalid compression format: %d\n"),format);return -1;}return 0;}int codec_decode(int format, const char *buff, size_t n, struct iobuff *iobout){switch(format) {case AUDIO_COMPRESSION_NONE:iob_queue(iobout, buff, n);break;#ifdef HAVE_LIBGSMcase AUDIO_COMPRESSION_GSM:codec_gsm_decode(buff, n, iobout);break;#endifcase AUDIO_COMPRESSION_G711U:codec_g711u_decode(buff, n, iobout);break;case AUDIO_COMPRESSION_G711A:codec_g711a_decode(buff, n, iobout);break;#ifdef HAVE_G72Xcase AUDIO_COMPRESSION_G721:case AUDIO_COMPRESSION_G723_24:case AUDIO_COMPRESSION_G723_40:codec_g72x_decode(format, buff, n, iobout);break;#endifdefault:fprintf(stderr, _("Error: codec_decode called with invalid compression format: %d\n"),format);return -1;}return 0;}void codecs_init(void){#ifdef HAVE_LIBGSMif (!g_init) {g_handle = gsm_create();g_init = 1;}#endif#ifdef HAVE_G72Xg72x_init_state(&g72xe_state);g72x_init_state(&g72xd_state);out_buffer = in_buffer = 0;out_bits = in_bits = 0;#endif}

⌨️ 快捷键说明

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