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

📄 msg711.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * G711 handling (includes A-Law & MU-Law) * *      Copyright (C) 2002		Eric Pouech * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <assert.h>#include <stdarg.h>#include <string.h>#include "windef.h"#include "winbase.h"#include "wingdi.h"#include "winuser.h"#include "winnls.h"#include "mmsystem.h"#include "mmreg.h"#include "msacm.h"#include "../msacmdrv.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(g711);/*********************************************************************** *           G711_drvOpen */static	DWORD	G711_drvOpen(LPCSTR str){    return 1;}/*********************************************************************** *           G711_drvClose */static	DWORD	G711_drvClose(DWORD dwDevID){    return 1;}typedef struct tagAcmG711Data{    void (*convert)(PACMDRVSTREAMINSTANCE adsi,		    const unsigned char*, LPDWORD, unsigned char*, LPDWORD);} AcmG711Data;/* table to list all supported formats... those are the basic ones. this * also helps given a unique index to each of the supported formats */typedef	struct{    int		nChannels;    int		nBits;    int		rate;} Format;static Format PCM_Formats[] ={    /*{1,  8,  8000}, {2,  8,  8000}, */{1, 16,  8000}, {2, 16,  8000},    /*{1,  8, 11025}, {2,  8, 11025}, */{1, 16, 11025}, {2, 16, 11025},    /*{1,  8, 22050}, {2,  8, 22050}, */{1, 16, 22050}, {2, 16, 22050},    /*{1,  8, 44100}, {2,  8, 44100}, */{1, 16, 44100}, {2, 16, 44100},};static Format ALaw_Formats[] ={    {1,  8,  8000}, {2,	8,  8000},  {1,  8, 11025}, {2,	 8, 11025},    {1,  8, 22050}, {2,	8, 22050},  {1,  8, 44100}, {2,	 8, 44100},};static Format ULaw_Formats[] ={    {1,  8,  8000}, {2,	8,  8000},  {1,  8, 11025}, {2,	 8, 11025},    {1,  8, 22050}, {2,	8, 22050},  {1,  8, 44100}, {2,	 8, 44100},};#define	NUM_PCM_FORMATS		(sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))#define	NUM_ALAW_FORMATS	(sizeof(ALaw_Formats) / sizeof(ALaw_Formats[0]))#define	NUM_ULAW_FORMATS	(sizeof(ULaw_Formats) / sizeof(ULaw_Formats[0]))/*********************************************************************** *           G711_GetFormatIndex */static	DWORD	G711_GetFormatIndex(LPWAVEFORMATEX wfx){    int 	i, hi;    Format*	fmts;    switch (wfx->wFormatTag)    {    case WAVE_FORMAT_PCM:	hi = NUM_PCM_FORMATS;	fmts = PCM_Formats;	break;    case WAVE_FORMAT_ALAW:	hi = NUM_ALAW_FORMATS;	fmts = ALaw_Formats;	break;    case WAVE_FORMAT_MULAW:	hi = NUM_ULAW_FORMATS;	fmts = ULaw_Formats;	break;    default:	return 0xFFFFFFFF;    }    for (i = 0; i < hi; i++)    {	if (wfx->nChannels == fmts[i].nChannels &&	    wfx->nSamplesPerSec == fmts[i].rate &&	    wfx->wBitsPerSample == fmts[i].nBits)	    return i;    }    return 0xFFFFFFFF;}/*********************************************************************** *           R16 * * Read a 16 bit sample (correctly handles endianess) */static inline short  R16(const unsigned char* src){    return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));}/*********************************************************************** *           W16 * * Write a 16 bit sample (correctly handles endianess) */static inline void  W16(unsigned char* dst, short s){    dst[0] = LOBYTE(s);    dst[1] = HIBYTE(s);}/* You can uncomment this if you don't want the statically generated conversion * table, but rather recompute the Xlaw => PCM conversion for each sample#define NO_FASTDECODE * Since the conversion tables are rather small (2k), I don't think it's really * interesting not to use them, but keeping the actual conversion code around * is helpful to regenerate the tables when needed. *//* -------------------------------------------------------------------------------*//* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use.  Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California  94043 *//* * g711.c * * u-law, A-law and linear PCM conversions. *//* * December 30, 1994: * Functions linear2alaw, linear2ulaw have been updated to correctly * convert unquantized 16 bit values. * Tables for direct u- to A-law and A- to u-law conversions have been * corrected. * Borge Lindberg, Center for PersonKommunikation, Aalborg University. * bli@cpk.auc.dk * */#define	SIGN_BIT	(0x80)		/* Sign bit for a A-law byte. */#define	QUANT_MASK	(0xf)		/* Quantization field mask. */#define	NSEGS		(8)		/* Number of A-law segments. */#define	SEG_SHIFT	(4)		/* Left shift for segment number. */#define	SEG_MASK	(0x70)		/* Segment field mask. */static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,			    0x1FF, 0x3FF, 0x7FF, 0xFFF};static short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,			    0x3FF, 0x7FF, 0xFFF, 0x1FFF};/* copy from CCITT G.711 specifications */static unsigned char _u2a[128] = {			/* u- to A-law conversions */	1,	1,	2,	2,	3,	3,	4,	4,	5,	5,	6,	6,	7,	7,	8,	8,	9,	10,	11,	12,	13,	14,	15,	16,	17,	18,	19,	20,	21,	22,	23,	24,	25,	27,	29,	31,	33,	34,	35,	36,	37,	38,	39,	40,	41,	42,	43,	44,	46,	48,	49,	50,	51,	52,	53,	54,	55,	56,	57,	58,	59,	60,	61,	62,	64,	65,	66,	67,	68,	69,	70,	71,	72,	73,	74,	75,	76,	77,	78,	79,/* corrected:	81,	82,	83,	84,	85,	86,	87,	88,   should be: */	80,	82,	83,	84,	85,	86,	87,	88,	89,	90,	91,	92,	93,	94,	95,	96,	97,	98,	99,	100,	101,	102,	103,	104,	105,	106,	107,	108,	109,	110,	111,	112,	113,	114,	115,	116,	117,	118,	119,	120,	121,	122,	123,	124,	125,	126,	127,	128};static unsigned char _a2u[128] = {			/* A- to u-law conversions */	1,	3,	5,	7,	9,	11,	13,	15,	16,	17,	18,	19,	20,	21,	22,	23,	24,	25,	26,	27,	28,	29,	30,	31,	32,	32,	33,	33,	34,	34,	35,	35,	36,	37,	38,	39,	40,	41,	42,	43,	44,	45,	46,	47,	48,	48,	49,	49,	50,	51,	52,	53,	54,	55,	56,	57,	58,	59,	60,	61,	62,	63,	64,	64,	65,	66,	67,	68,	69,	70,	71,	72,/* corrected:	73,	74,	75,	76,	77,	78,	79,	79,   should be: */	73,	74,	75,	76,	77,	78,	79,	80,	80,	81,	82,	83,	84,	85,	86,	87,	88,	89,	90,	91,	92,	93,	94,	95,	96,	97,	98,	99,	100,	101,	102,	103,	104,	105,	106,	107,	108,	109,	110,	111,	112,	113,	114,	115,	116,	117,	118,	119,	120,	121,	122,	123,	124,	125,	126,	127};static shortsearch(    int		val,	        /* changed from "short" *drago* */    short	*table,    int		size)	        /* changed from "short" *drago* */{    int		i;	/* changed from "short" *drago* */    for (i = 0; i < size; i++) {        if (val <= *table++)            return (i);    }    return (size);}/* * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law * * linear2alaw() accepts an 16-bit integer and encodes it as A-law data. * *		Linear Input Code	Compressed Code *	------------------------	--------------- *	0000000wxyza			000wxyz *	0000001wxyza			001wxyz *	000001wxyzab			010wxyz *	00001wxyzabc			011wxyz *	0001wxyzabcd			100wxyz *	001wxyzabcde			101wxyz *	01wxyzabcdef			110wxyz *	1wxyzabcdefg			111wxyz * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */static inline unsigned charlinear2alaw(int pcm_val)	/* 2's complement (16-bit range) */    /* changed from "short" *drago* */{    int		mask;	/* changed from "short" *drago* */    int		seg;	/* changed from "short" *drago* */    unsigned char	aval;    pcm_val = pcm_val >> 3;    if (pcm_val >= 0) {        mask = 0xD5;		/* sign (7th) bit = 1 */    } else {        mask = 0x55;		/* sign bit = 0 */        pcm_val = -pcm_val - 1;    }    /* Convert the scaled magnitude to segment number. */    seg = search(pcm_val, seg_aend, 8);    /* Combine the sign, segment, and quantization bits. */    if (seg >= 8)		/* out of range, return maximum value. */        return (unsigned char) (0x7F ^ mask);    else {        aval = (unsigned char) seg << SEG_SHIFT;        if (seg < 2)            aval |= (pcm_val >> 1) & QUANT_MASK;        else            aval |= (pcm_val >> seg) & QUANT_MASK;        return (aval ^ mask);    }}#ifdef NO_FASTDECODE/* * alaw2linear() - Convert an A-law value to 16-bit linear PCM * */static inline intalaw2linear(unsigned char a_val){    int		t;	/* changed from "short" *drago* */    int		seg;	/* changed from "short" *drago* */    a_val ^= 0x55;    t = (a_val & QUANT_MASK) << 4;    seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;    switch (seg) {    case 0:        t += 8;        break;    case 1:        t += 0x108;        break;    default:        t += 0x108;        t <<= seg - 1;    }    return ((a_val & SIGN_BIT) ? t : -t);}#else/* EPP (for Wine): * this array has been statically generated from the above routine */static unsigned short _a2l[] = {0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80,0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0,0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600,0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00,0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00,0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8,0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58,0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8,0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58,0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60,0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960,0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0,0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0,0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280,0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80,0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940,0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40,0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00,0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00,0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500,0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500,0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128,0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8,0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028,0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8,0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0,

⌨️ 快捷键说明

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