📄 mpeglayer3.cc
字号:
/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */// Mpeglayer3.cc// It's for MPEG Layer 3// I've made array of superior functions for speed.// Extend TO_FOUR_THIRDS to negative.// Bug fix : maplay 1.2+ have wrong TO_FOUR_THIRDS ranges.// Force to mono!!// MPEG-2 is implemented// Speed up in fixstereo (maybe buggy) //// Fixed point support by Nicolas Pitre <nico@cam.org>#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include <stdlib.h>#include "mpegsound.h"#include "mpegsound_locals.h"inline voidMpegbitwindow::wrap(void){ int p = bitindex >> 3; point &= (WINDOWSIZE - 1); if (p >= point) { for (register int i = 4; i < point; i++) buffer[WINDOWSIZE + i] = buffer[i]; } *((int *) (buffer + WINDOWSIZE)) = *((int *) buffer);}inline intMpegbitwindow::getbit(void){// register int r=(buffer[(bitindex>>3)&(WINDOWSIZE-1)]>>(7-(bitindex&7)))&1; register int r = (buffer[bitindex >> 3] >> (7 - (bitindex & 7))) & 1; bitindex++; return r;};inline intMpegbitwindow::getbits9(int bits){ register unsigned short a;#ifndef WORDS_BIGENDIAN { // int offset=(bitindex>>3)&(WINDOWSIZE-1); int offset = bitindex >> 3; a = (((unsigned char) buffer[offset]) << 8) | ((unsigned char) buffer[offset + 1]); }#else // a=((unsigned short *)(buffer+((bixindex>>3)&(WINDOWSIZE-1)))); a = ((unsigned short *) (buffer + ((bixindex >> 3))));#endif a <<= (bitindex & 7); bitindex += bits; return (int) ((unsigned int) (a >> (16 - bits)));}inline intMpegtoraw::wgetbit(void){ return bitwindow.getbit();}inline intMpegtoraw::wgetbits9(int bits){ return bitwindow.getbits9(bits);}inline intMpegtoraw::wgetbits(int bits){ return bitwindow.getbits(bits);}#define MUL3(a) (((a)<<1)+(a))#define REAL0 0#define ARRAYSIZE (SBLIMIT*SSLIMIT)#define REALSIZE (sizeof(REAL))#ifdef NATIVE_ASSEMBLYinline voidlong_memset(void *s, unsigned int c, int count){ __asm__ __volatile__("cld\n\t" "rep ; stosl\n\t": /* no output */ :"a"(c), "c"(count / 4), "D"((long) s) :"cx", "di", "memory");}#endif#define FOURTHIRDSTABLENUMBER (1<<13)#define TO_FOUR_THIRDS(x) \ (((x) >= 0) ? TO_FOUR_THIRDSTABLE[(x)] \ : -TO_FOUR_THIRDSTABLE[-(x)])typedef struct{ REAL l, r;}RATIOS;#include "mpeglayer3tables.h"voidMpegtoraw::layer3initialize(void){ layer3framestart = 0; currentprevblock = 0; { int i, j, k, l; for (l = 0; l < 2; l++) for (i = 0; i < 2; i++) for (j = 0; j < SBLIMIT; j++) for (k = 0; k < SSLIMIT; k++) prevblck[l][i][j][k] = 0.0f; } bitwindow.initialize();}boolMpegtoraw::layer3getsideinfo(void){ sideinfo.main_data_begin = getbits(9); if (!inputstereo) sideinfo.private_bits = getbits(5); else sideinfo.private_bits = getbits(3); sideinfo.ch[LS].scfsi[0] = getbit(); sideinfo.ch[LS].scfsi[1] = getbit(); sideinfo.ch[LS].scfsi[2] = getbit(); sideinfo.ch[LS].scfsi[3] = getbit(); if (inputstereo) { sideinfo.ch[RS].scfsi[0] = getbit(); sideinfo.ch[RS].scfsi[1] = getbit(); sideinfo.ch[RS].scfsi[2] = getbit(); sideinfo.ch[RS].scfsi[3] = getbit(); } for (int gr = 0, ch; gr < 2; gr++) for (ch = 0;; ch++) { layer3grinfo *gi = &(sideinfo.ch[ch].gr[gr]); gi->part2_3_length = getbits(12); gi->big_values = getbits(9); gi->global_gain = getbits(8); gi->scalefac_compress = getbits(4); gi->window_switching_flag = getbit(); if (gi->window_switching_flag) { gi->block_type = getbits(2); gi->mixed_block_flag = getbit(); gi->table_select[0] = getbits(5); gi->table_select[1] = getbits(5); gi->subblock_gain[0] = getbits(3); gi->subblock_gain[1] = getbits(3); gi->subblock_gain[2] = getbits(3); /* Set region_count parameters since they are implicit in this case. */ if (gi->block_type == 0) { /* printf("Side info bad: block_type == 0 in split block.\n"); exit(0); */ return false; } else if (gi->block_type == 2 && gi->mixed_block_flag == 0) gi->region0_count = 8; /* MI 9; */ else gi->region0_count = 7; /* MI 8; */ gi->region1_count = 20 - (gi->region0_count); } else { gi->table_select[0] = getbits(5); gi->table_select[1] = getbits(5); gi->table_select[2] = getbits(5); gi->region0_count = getbits(4); gi->region1_count = getbits(3); gi->block_type = 0; } gi->preflag = getbit(); gi->scalefac_scale = getbit(); gi->count1table_select = getbit(); gi->generalflag = gi->window_switching_flag && (gi->block_type == 2); if (!inputstereo || ch) break; } return true;}boolMpegtoraw::layer3getsideinfo_2(void){ sideinfo.main_data_begin = getbits(8); if (!inputstereo) sideinfo.private_bits = getbit(); else sideinfo.private_bits = getbits(2); for (int ch = 0;; ch++) { layer3grinfo *gi = &(sideinfo.ch[ch].gr[0]); gi->part2_3_length = getbits(12); gi->big_values = getbits(9); gi->global_gain = getbits(8); gi->scalefac_compress = getbits(9); gi->window_switching_flag = getbit(); if (gi->window_switching_flag) { gi->block_type = getbits(2); gi->mixed_block_flag = getbit(); gi->table_select[0] = getbits(5); gi->table_select[1] = getbits(5); gi->subblock_gain[0] = getbits(3); gi->subblock_gain[1] = getbits(3); gi->subblock_gain[2] = getbits(3); /* Set region_count parameters since they are implicit in this case. */ if (gi->block_type == 0) { /* printf("Side info bad: block_type == 0 in split block.\n"); exit(0); */ return false; } else if (gi->block_type == 2 && gi->mixed_block_flag == 0) gi->region0_count = 8; /* MI 9; */ else gi->region0_count = 7; /* MI 8; */ gi->region1_count = 20 - (gi->region0_count); } else { gi->table_select[0] = getbits(5); gi->table_select[1] = getbits(5); gi->table_select[2] = getbits(5); gi->region0_count = getbits(4); gi->region1_count = getbits(3); gi->block_type = 0; } gi->scalefac_scale = getbit(); gi->count1table_select = getbit(); gi->generalflag = gi->window_switching_flag && (gi->block_type == 2); if (!inputstereo || ch) break; } return true;}voidMpegtoraw::layer3getscalefactors(int ch, int gr){ static int slen[2][16] = { {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3} }; layer3grinfo *gi = &(sideinfo.ch[ch].gr[gr]); register layer3scalefactor *sf = (&scalefactors[ch]); int l0, l1; { int scale_comp = gi->scalefac_compress; l0 = slen[0][scale_comp]; l1 = slen[1][scale_comp]; } if (gi->generalflag) { if (gi->mixed_block_flag) { /* MIXED *//* NEW-ag 11/25 */ sf->l[0] = wgetbits9(l0); sf->l[1] = wgetbits9(l0); sf->l[2] = wgetbits9(l0); sf->l[3] = wgetbits9(l0); sf->l[4] = wgetbits9(l0); sf->l[5] = wgetbits9(l0); sf->l[6] = wgetbits9(l0); sf->l[7] = wgetbits9(l0); sf->s[0][3] = wgetbits9(l0); sf->s[1][3] = wgetbits9(l0); sf->s[2][3] = wgetbits9(l0); sf->s[0][4] = wgetbits9(l0); sf->s[1][4] = wgetbits9(l0); sf->s[2][4] = wgetbits9(l0); sf->s[0][5] = wgetbits9(l0); sf->s[1][5] = wgetbits9(l0); sf->s[2][5] = wgetbits9(l0); sf->s[0][6] = wgetbits9(l1); sf->s[1][6] = wgetbits9(l1); sf->s[2][6] = wgetbits9(l1); sf->s[0][7] = wgetbits9(l1); sf->s[1][7] = wgetbits9(l1); sf->s[2][7] = wgetbits9(l1); sf->s[0][8] = wgetbits9(l1); sf->s[1][8] = wgetbits9(l1); sf->s[2][8] = wgetbits9(l1); sf->s[0][9] = wgetbits9(l1); sf->s[1][9] = wgetbits9(l1); sf->s[2][9] = wgetbits9(l1); sf->s[0][10] = wgetbits9(l1); sf->s[1][10] = wgetbits9(l1); sf->s[2][10] = wgetbits9(l1); sf->s[0][11] = wgetbits9(l1); sf->s[1][11] = wgetbits9(l1); sf->s[2][11] = wgetbits9(l1); sf->s[0][12] = sf->s[1][12] = sf->s[2][12] = 0; } else { /* SHORT */ sf->s[0][0] = wgetbits9(l0); sf->s[1][0] = wgetbits9(l0); sf->s[2][0] = wgetbits9(l0); sf->s[0][1] = wgetbits9(l0); sf->s[1][1] = wgetbits9(l0); sf->s[2][1] = wgetbits9(l0); sf->s[0][2] = wgetbits9(l0); sf->s[1][2] = wgetbits9(l0); sf->s[2][2] = wgetbits9(l0); sf->s[0][3] = wgetbits9(l0); sf->s[1][3] = wgetbits9(l0); sf->s[2][3] = wgetbits9(l0); sf->s[0][4] = wgetbits9(l0); sf->s[1][4] = wgetbits9(l0); sf->s[2][4] = wgetbits9(l0); sf->s[0][5] = wgetbits9(l0); sf->s[1][5] = wgetbits9(l0); sf->s[2][5] = wgetbits9(l0); sf->s[0][6] = wgetbits9(l1); sf->s[1][6] = wgetbits9(l1); sf->s[2][6] = wgetbits9(l1); sf->s[0][7] = wgetbits9(l1); sf->s[1][7] = wgetbits9(l1); sf->s[2][7] = wgetbits9(l1); sf->s[0][8] = wgetbits9(l1); sf->s[1][8] = wgetbits9(l1); sf->s[2][8] = wgetbits9(l1); sf->s[0][9] = wgetbits9(l1); sf->s[1][9] = wgetbits9(l1); sf->s[2][9] = wgetbits9(l1); sf->s[0][10] = wgetbits9(l1); sf->s[1][10] = wgetbits9(l1); sf->s[2][10] = wgetbits9(l1); sf->s[0][11] = wgetbits9(l1); sf->s[1][11] = wgetbits9(l1); sf->s[2][11] = wgetbits9(l1); sf->s[0][12] = sf->s[1][12] = sf->s[2][12] = 0; } } else { /* LONG types 0,1,3 */ if (gr == 0) { sf->l[0] = wgetbits9(l0); sf->l[1] = wgetbits9(l0); sf->l[2] = wgetbits9(l0); sf->l[3] = wgetbits9(l0); sf->l[4] = wgetbits9(l0); sf->l[5] = wgetbits9(l0); sf->l[6] = wgetbits9(l0); sf->l[7] = wgetbits9(l0); sf->l[8] = wgetbits9(l0); sf->l[9] = wgetbits9(l0); sf->l[10] = wgetbits9(l0); sf->l[11] = wgetbits9(l1); sf->l[12] = wgetbits9(l1); sf->l[13] = wgetbits9(l1); sf->l[14] = wgetbits9(l1); sf->l[15] = wgetbits9(l1); sf->l[16] = wgetbits9(l1); sf->l[17] = wgetbits9(l1); sf->l[18] = wgetbits9(l1); sf->l[19] = wgetbits9(l1); sf->l[20] = wgetbits9(l1); } else { if (sideinfo.ch[ch].scfsi[0] == 0) { sf->l[0] = wgetbits9(l0); sf->l[1] = wgetbits9(l0); sf->l[2] = wgetbits9(l0); sf->l[3] = wgetbits9(l0); sf->l[4] = wgetbits9(l0); sf->l[5] = wgetbits9(l0); } if (sideinfo.ch[ch].scfsi[1] == 0) { sf->l[6] = wgetbits9(l0); sf->l[7] = wgetbits9(l0); sf->l[8] = wgetbits9(l0); sf->l[9] = wgetbits9(l0); sf->l[10] = wgetbits9(l0); } if (sideinfo.ch[ch].scfsi[2] == 0) { sf->l[11] = wgetbits9(l1); sf->l[12] = wgetbits9(l1); sf->l[13] = wgetbits9(l1); sf->l[14] = wgetbits9(l1); sf->l[15] = wgetbits9(l1); } if (sideinfo.ch[ch].scfsi[3] == 0) { sf->l[16] = wgetbits9(l1); sf->l[17] = wgetbits9(l1); sf->l[18] = wgetbits9(l1); sf->l[19] = wgetbits9(l1); sf->l[20] = wgetbits9(l1); } } sf->l[21] = sf->l[22] = 0; }}voidMpegtoraw::layer3getscalefactors_2(int ch){ static int sfbblockindex[6][3][4] = { {{6, 5, 5, 5}, {9, 9, 9, 9}, {6, 9, 9, 9}}, {{6, 5, 7, 3}, {9, 9, 12, 6}, {6, 9, 12, 6}}, {{11, 10, 0, 0}, {18, 18, 0, 0}, {15, 18, 0, 0}}, {{7, 7, 7, 0}, {12, 12, 12, 0}, {6, 15, 12, 0}}, {{6, 6, 6, 3}, {12, 9, 9, 6}, {6, 12, 9, 6}}, {{8, 8, 5, 0}, {15, 12, 9, 0}, {6, 18, 9, 0}} }; int sb[54]; layer3grinfo *gi = &(sideinfo.ch[ch].gr[0]); register layer3scalefactor *sf = (&scalefactors[ch]); { int blocktypenumber, sc; int blocknumber; int slen[4]; if (gi->block_type == 2) blocktypenumber = 1 + gi->mixed_block_flag; else blocktypenumber = 0; sc = gi->scalefac_compress; if (!((extendedmode == 1 || extendedmode == 3) && (ch == 1))) { if (sc < 400) { slen[0] = (sc >> 4) / 5; slen[1] = (sc >> 4) % 5; slen[2] = (sc % 16) >> 2; slen[3] = (sc % 4); gi->preflag = 0; blocknumber = 0; } else if (sc < 500) { sc -= 400; slen[0] = (sc >> 2) / 5; slen[1] = (sc >> 2) % 5; slen[2] = sc % 4; slen[3] = 0; gi->preflag = 0; blocknumber = 1; } else // if(sc<512) { sc -= 500; slen[0] = sc / 3; slen[1] = sc % 3; slen[2] = 0; slen[3] = 0; gi->preflag = 1; blocknumber = 2; } } else { sc >>= 1; if (sc < 180) { slen[0] = sc / 36; slen[1] = (sc % 36) / 6; slen[2] = (sc % 36) % 6; slen[3] = 0; gi->preflag = 0; blocknumber = 3; } else if (sc < 244) { sc -= 180; slen[0] = (sc % 64) >> 4; slen[1] = (sc % 16) >> 2; slen[2] = sc % 4; slen[3] = 0; gi->preflag = 0; blocknumber = 4; } else // if(sc<255) { sc -= 244; slen[0] = sc / 3; slen[1] = sc % 3; slen[2] = slen[3] = 0; gi->preflag = 0; blocknumber = 5; } } { int i, j, k, *si; si = sfbblockindex[blocknumber][blocktypenumber]; for (i = 0; i < 45; i++) sb[i] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -