📄 layer2.c
字号:
#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 + -