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

📄 layer2.c

📁 由bmp生成mpeg2 的I_frame 数据
💻 C
📖 第 1 页 / 共 5 页
字号:
#define LAYER2_C

#include <string.h>
#include <float.h>
#include "layer2.h"
#include "memory_stream.h"

void init_layer2_work(LAYER2_WORK *work);
int parse_layer2_header(unsigned int sync, LAYER2_HEADER *out);
int decode_layer2(LAYER2_HEADER *head, unsigned char *buffer, LAYER2_WORK *work, short *pcm);

static int decode_layer2_stereo(LAYER2_HEADER *head, unsigned char *buffer, LAYER2_WORK *work, short *pcm);
static int decode_layer2_monaural(LAYER2_HEADER *head, unsigned char *buffer, LAYER2_WORK *work, short *pcm);

void init_layer2_work(LAYER2_WORK *work)
{
	memset(work->area, 0, sizeof(work->area));
	work->offset = 0;
}

int parse_layer2_header(unsigned int sync, LAYER2_HEADER *out)
{
	int channel_bitrate;
	static const int sblimit = 32;
	
	static const int bitrate[16] = {
		-1, 32000, 48000, 56000, 64000, 80000, 96000, 112000,
		128000, 160000, 192000, 224000, 256000, 320000, 384000, 0
	};

	static const int frequency[4] = {
		44100, 48000, 32000, 0,
	};

	if( (sync & 0xfff00000) != 0xfff00000 ){
		goto LAYER2_PARSE_HEADER_ERROR;
	}

	if( ((sync >> 19) & 1) == 1 ){
		out->version = 1;
	}

	switch((sync >> 17) & 3){
	case 0:
		/* undefined layer */
		goto LAYER2_PARSE_HEADER_ERROR;
	case 1:
		/* layer3 */
		goto LAYER2_PARSE_HEADER_ERROR;
	case 2:
		out->layer = 2;
		break;
	case 3:
		/* layer1 */
		goto LAYER2_PARSE_HEADER_ERROR;
	}

	out->has_crc = ((sync >> 16) & 1) ^ 1;

	out->bitrate = bitrate[(sync >> 12) & 0xf];
	if(out->bitrate < 1){
		goto LAYER2_PARSE_HEADER_ERROR;
	}
	out->frequency = frequency[(sync >> 10) & 3];
	if(out->frequency == 0){
		goto LAYER2_PARSE_HEADER_ERROR;
	}
	out->padding = (sync >> 9) & 1;

	switch((sync >> 6) & 3){
	case 0:
		/* stereo */
		out->channel = 2;
		out->bound = sblimit;
		break;
	case 1:
		/* intensity stereo */
		out->channel = 2;
		out->bound = (((sync >> 4) & 3) + 1) << 2;
		break;
	case 2:
		/* dual channel */
		out->channel = 2;
		out->bound = sblimit;
		break;
	case 3:
		/* monaural */
		out->channel = 1;
		out->bound = sblimit;
		break;
	}

	out->emphasis = sync & 3;

	if(out->bitrate < 1){
		/* free format is not supported */
		goto LAYER2_PARSE_HEADER_ERROR;
	}

	if(out->channel == 2){
		channel_bitrate = out->bitrate / 2;
		if(channel_bitrate < 32000){
			/* unsupported bitrate */
			goto LAYER2_PARSE_HEADER_ERROR;
		}
	}else{
		channel_bitrate = out->bitrate;
		if(channel_bitrate > 192000){
			/* unsupported bitrate */
			goto LAYER2_PARSE_HEADER_ERROR;
		}
	}

	if(channel_bitrate < 56000){
		if(out->frequency == 32000){
			out->sblimit = 12;
		}else{
			out->sblimit = 8;
		}
	}else if(channel_bitrate < 96000){
		out->sblimit = 27;
	}else{
		if(out->frequency == 48000){
			out->sblimit = 27;
		}else{
			out->sblimit = 30;
		}
	}
	if(out->bound > out->sblimit){
		out->bound = out->sblimit;
	}
	
	switch(out->version){
	case 1:
		out->framesize = 144*out->bitrate/out->frequency+out->padding;
		break;
	default: 
		/* only support MPEG-1 */
		goto LAYER2_PARSE_HEADER_ERROR; 
	}

	return 1;
	
LAYER2_PARSE_HEADER_ERROR:
	memset(out, 0, sizeof(LAYER2_HEADER));
	return 0;
}

static const double table_b1[] = {
	2.00000000000000, 1.58740105196820, 1.25992104989487, 1.00000000000000,
	0.79370042498410, 0.62996052494744, 0.50000000000000, 0.39685026299205,
	0.31498026247372, 0.25000000000000, 0.19842513149602, 0.15749013123686,
	0.12500000000000, 0.09921256574801, 0.07874506561843, 0.06250000000000,

	0.04960628287401, 0.03937253280921, 0.03125000000000, 0.02480314143700,
	0.01968626640461, 0.01562500000000, 0.01240157071850, 0.00984313320230,
	0.00781250000000, 0.00620078535925, 0.00492156660115, 0.00390625000000,
	0.00310039267963, 0.00246078330058, 0.00195312500000, 0.00155019633981,
	
	0.00123039165029, 0.00097656250000, 0.00077509816991, 0.00061519582514,
	0.00048828125000, 0.00038754908495, 0.00030759791257, 0.00024414062500,
	0.00019377454248, 0.00015379895629, 0.00012207031250, 0.00009688727124,
	0.00007689947814, 0.00006103515625, 0.00004844363562, 0.00003844973907,

	0.00003051757813, 0.00002422181781, 0.00001922486954, 0.00001525878906,
	0.00001211090890, 0.00000961243477, 0.00000762939453, 0.00000605545445,
	0.00000480621738, 0.00000381469727, 0.00000302772723, 0.00000240310869,
	0.00000190734863, 0.00000151386361, 0.00000120155435, 0.0
};
	
static const int table_b2ab_nbal[] = {
	4, 4, 4, 4, 4, 4, 4, 4,
	4, 4, 4, 3, 3, 3, 3, 3,
	3, 3, 3, 3, 3, 3, 3, 2,
	2, 2, 2, 2, 2, 2, 0, 0,
};

static const int table_b2cd_nbal[] = {
	4, 4, 3, 3, 3, 3, 3, 3,
	3, 3, 3, 3, 0, 0, 0, 0,
};

static const int table_b2_4a[] = {
	0,  1,  4,  5,  6,  7,  8,  9,
	10, 11, 12, 13, 14, 15, 16, 17,
};

static const int table_b2_4b[] = {
	0,  1,  2,  4,  3,  5,  6,  7,
	8,  9, 10, 11, 12, 13, 14, 17,
};

static const int table_b2_4c[] = {
	0,  1,  2,  3,  5,  6,  7,  8,
	9, 10, 11, 12, 13, 14, 15, 16,
};

static const int table_b2_3a[] = {
	0, 1, 2, 4, 3, 5, 6, 17,
};

static const int table_b2_3b[] = {
	0, 1, 2, 3, 5, 6, 7, 8,
};

static const int table_b2_2[] = {
	0, 1, 2, 17,
};

static const int *table_b2ab[] = {
	table_b2_4a, table_b2_4a, table_b2_4a, table_b2_4b,
	table_b2_4b, table_b2_4b, table_b2_4b, table_b2_4b,

⌨️ 快捷键说明

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