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

📄 pcm.c

📁 G726标准的24kbps和40kbps两种比特率的音频编解码算法源代码
💻 C
字号:
#include "pcm.h"

static const short alaw_seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};

static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; 

/*	Linear Code		Compressed Code
	---------------		---------------
	0000000wxyza		000wxyz
	0000001wxyza		001wxyz
	000001wxyzab		010wxyz
	00001wxyzabc		011wxyz
	0001wxyzabcd		100wxyz
	001wxyzabcde		101wxyz
	01wxyzabcdef		110wxyz
	1wxyzabcdefg		111wxyz
*/


static int search(int val, const short *table, int size)
{
	int i;
	
	for (i = 0; i < size; i++) {
		if (val <= *table++)
			return (i);
	}
	return (size);
}

unsigned char linear2alaw(short pcm_val)     /* 2's complement (16-bit range) */
{
	int mask;
	int seg;
	unsigned char aval;

	pcm_val &= 0xfff8;

	if (pcm_val >= 0) {
		mask = 0xD5;            /* sign (7th) bit = 1 */
	} 
	else {
		mask = 0x55;            /* sign bit = 0 */
		pcm_val = -pcm_val - 8;
	}

	/* Convert the scaled magnitude to segment number. */
	seg = search(pcm_val, alaw_seg_end, NSEGS);

	/* 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 >> 4) & QUANT_MASK;
		else
			aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
		return (unsigned char)(aval ^ mask);
	}
}

short alaw2linear(unsigned char a_val)
{
	short t;
	int seg;

	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);
}

unsigned char 
linear2ulaw( 
			int pcm_val) /* 2's complement (16-bit range) */ 
{ 
	int mask; 
	int seg; 
	unsigned char uval; 
	
	/* Get the sign and the magnitude of the value. */ 
	if (pcm_val < 0) { 
		pcm_val = BIAS - pcm_val; 
		mask = 0x7F; 
	} else { 
		pcm_val += BIAS; 
		mask = 0xFF; 
	} 
	
	/* Convert the scaled magnitude to segment number. */ 
	seg = search(pcm_val, seg_end, 8); 
	
	/* 
	* Combine the sign, segment, quantization bits; 
	* and complement the code word. 
	*/ 
	if (seg >= 8) /* out of range, return maximum value. */ 
		return (0x7F ^ mask); 
	else { 
		uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); 
		return (uval ^ mask); 
	} 
	
} 

/* 
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM 
* 
* First, a biased linear code is derived from the code word. An unbiased 
* output can then be obtained by subtracting 33 from the biased code. 
* 
* Note that this function expects to be passed the complement of the 
* original code word. This is in keeping with ISDN conventions. 
*/ 
int 
ulaw2linear( 
			unsigned char u_val) 
{ 
	int t; 
	
	/* Complement to obtain normal u-law value. */ 
	u_val = ~u_val; 
	
	/* 
	* Extract and bias the quantization bits. Then 
	* shift up by the segment number and subtract out the bias. 
	*/ 
	t = ((u_val & QUANT_MASK) << 3) + BIAS; 
	t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; 
	
	return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); 
} 

⌨️ 快捷键说明

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